> First, the skb_header_cloned() patch I posted in another reply will > get rid of copying due to clones. I've included it below for > completeness. > > The next problem is to make sure there is enough space available. And > all that's needed is some help from the bridging layer and some hooks > into netdev_alloc_skb(). > > On bridge transmit, it knows the input and output devices, and the > requirements of LL header space on the transmit side. > > If the transmit requirements are not met for the received packet, we > can tag the difference into the input netdev. > > Using that information we can allocate extra space in > netdev_alloc_skb(), and do an skb_reserve(). > > The only requirement is that the ethernet driver serving input packets > uses netdev_alloc_skb(). The most important drivers already do, and > those which do not are trivially converted. > > The following along with Johannes's needed_header et al. patch should > take care of the overhead. > > If this proves to be a working solution, we can do something similar > for IPv4 and IPv6 forwarding. At that point, we should make this > "adjust input device extra space" a helper function that all of > these spots can call. This looks feasible, thanks for looking into it. But isn't, when the bridge gives us a cloned skb, the complete header the complete data since it won't be a fraglist skb? And then we copy it all anyway? That's just for group addressed frames, of course, so still a lot better I guess. The main point is getting enough headroom. Also, should there be some sort of timer that resets the rx_alloc_extra again so that when you bridge it once with p54 (needs heaps of headroom) you don't suffer forever? > @@ -255,11 +255,12 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, > unsigned int length, gfp_t gfp_mask) > { > int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1; > + unsigned int extra = dev->rx_alloc_extra + NET_SKB_PAD; > struct sk_buff *skb; > > - skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, node); > + skb = __alloc_skb(length + extra, gfp_mask, 0, node); > if (likely(skb)) { > - skb_reserve(skb, NET_SKB_PAD); > + skb_reserve(skb, extra); Doesn't that break alignment though? johannes
Attachment:
signature.asc
Description: This is a digitally signed message part