<div dir="ltr">hi Alberto:<div> I'm confused with "<span style="font-size:14px"> </span><span style="font-size:14px">paging skbs is a technique meant to ease the work</span></div><span style="font-size:14px">of drivers.</span><span style="font-size:14px">A driver might choose to page "too much" data.</span>", please give more explain.<div><br></div><div>Thank you.</div></div><div class="gmail_extra"><br><div class="gmail_quote">2015-01-07 23:35 GMT+08:00 Alberto Leiva <span dir="ltr"><<a href="mailto:ydahhrk@gmail.com" target="_blank">ydahhrk@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I think in theory whatever random driver for whatever random hardware<br>
might create this situation. It's not illegal. Anyone can create a<br>
driver outside of the kernel tree, after all. In practice, of course,<br>
this is not the case, because anyone can tell it creates a significant<br>
amount of overhead when the inevitable pskb_may_pull() come into play,<br>
but you don't know what constrictive environments a driver out there<br>
might be operating on.<br>
<br>
As I understand it, paging skbs is a technique meant to ease the work<br>
of drivers.<br>
A driver might choose to page "too much" data.<br>
The kernel is prepared for this situation ('Be conservative in what<br>
you do, be liberal in what you accept from others' -<br>
<a href="http://en.wikipedia.org/wiki/Robustness_principle" target="_blank">http://en.wikipedia.org/wiki/Robustness_principle</a>).<br>
That's all there is to it, I think.<br>
<br>
PS: From your sorta definition, you seem to be assuming<br>
pskb_may_pull() is only used to ensure the IP header is not paged. I<br>
understand this might not be the case, but just to make things clear:<br>
pskb_may_pull() can be used to copy *any* amount of bytes from the<br>
paged part to the head room of the packet (it's not tied to the IP<br>
header's length). For example, you could use it to also guarantee a<br>
TCP header by doing this:<br>
if (!pskb_may_pull(skb, sizeof(struct iphdr) + sizeof(struct tcphdr)))<br>
goto inhdr_error;<br>
<div><div class="h5"><br>
<br>
On Wed, Jan 7, 2015 at 2:28 AM, lx <<a href="mailto:lxlenovostar@gmail.com">lxlenovostar@gmail.com</a>> wrote:<br>
> hi all:<br>
> The job of pskb_may_pull is to make sure that the area pointed to by<br>
> skb->data contains a block of<br>
> data at least as big as the IP header, since each IP packet (fragments<br>
> included) must include a complete IP<br>
> header.When we receive a packet , the kernel will call the pkb_may_pull(),<br>
> it looks like the following in line 395:<br>
><br>
> 373 /*<br>
> 374 * Main IP Receive routine.<br>
> 375 */<br>
> 376 int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct<br>
> packet_type *pt, struct net_device *orig_dev)<br>
> 377 {<br>
> 378 const struct iphdr *iph;<br>
> 379 u32 len;<br>
> 380<br>
> 381 /* When the interface is in promisc. mode, drop all the crap<br>
> 382 * that it receives, do not try to analyse it.<br>
> 383 */<br>
> 384 if (skb->pkt_type == PACKET_OTHERHOST)<br>
> 385 goto drop;<br>
> 386<br>
> 387<br>
> 388 IP_UPD_PO_STATS_BH(dev_net(dev), IPSTATS_MIB_IN, skb->len);<br>
> 389<br>
> 390 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {<br>
> 391 IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS);<br>
> 392 goto out;<br>
> 393 }<br>
> 394<br>
> 395 if (!pskb_may_pull(skb, sizeof(struct iphdr)))<br>
> 396 goto inhdr_error;<br>
> 397<br>
> 398 iph = ip_hdr(skb);<br>
> 399<br>
><br>
> And the definition of pkb_may_pull() looks like the following:<br>
><br>
> 1708 static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)<br>
> 1709 {<br>
> 1710 if (likely(len <= skb_headlen(skb)))<br>
> 1711 return 1;<br>
> 1712 if (unlikely(len > skb->len))<br>
> 1713 return 0;<br>
> 1714 return __pskb_pull_tail(skb, len - skb_headlen(skb)) != NULL;<br>
> 1715 }<br>
><br>
> I just want to know which situation make the skb->data contains a block of<br>
> data less than the IP header?<br>
> I think this packet can't send by kernel at all.<br>
> Thank you.<br>
><br>
</div></div>> _______________________________________________<br>
> Kernelnewbies mailing list<br>
> <a href="mailto:Kernelnewbies@kernelnewbies.org">Kernelnewbies@kernelnewbies.org</a><br>
> <a href="http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies" target="_blank">http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies</a><br>
><br>
</blockquote></div><br></div>