John Fastabend
2021-Feb-18 00:46 UTC
[PATCH v7 bpf-next 6/6] xsk: build skb by page (aka generic zerocopy xmit)
Alexander Lobakin wrote:> From: Xuan Zhuo <xuanzhuo at linux.alibaba.com> > > This patch is used to construct skb based on page to save memory copy > overhead. > > This function is implemented based on IFF_TX_SKB_NO_LINEAR. Only the > network card priv_flags supports IFF_TX_SKB_NO_LINEAR will use page to > directly construct skb. If this feature is not supported, it is still > necessary to copy data to construct skb. > > ---------------- Performance Testing ------------ > > The test environment is Aliyun ECS server. > Test cmd: > ``` > xdpsock -i eth0 -t -S -s <msg size> > ``` > > Test result data: > > size 64 512 1024 1500 > copy 1916747 1775988 1600203 1440054 > page 1974058 1953655 1945463 1904478 > percent 3.0% 10.0% 21.58% 32.3% > > Signed-off-by: Xuan Zhuo <xuanzhuo at linux.alibaba.com> > Reviewed-by: Dust Li <dust.li at linux.alibaba.com> > [ alobakin: > - expand subject to make it clearer; > - improve skb->truesize calculation; > - reserve some headroom in skb for drivers; > - tailroom is not needed as skb is non-linear ] > Signed-off-by: Alexander Lobakin <alobakin at pm.me> > Acked-by: Magnus Karlsson <magnus.karlsson at intel.com> > ---[...]> + buffer = xsk_buff_raw_get_data(pool, addr); > + offset = offset_in_page(buffer); > + addr = buffer - pool->addrs; > + > + for (copied = 0, i = 0; copied < len; i++) { > + page = pool->umem->pgs[addr >> PAGE_SHIFT];Looks like we could walk off the end of pgs[] if len is larger than the number of pgs? Do we need to guard against a misconfigured socket causing a panic here? AFAIU len here is read from the user space descriptor so is under user control. Or maybe I missed a check somewhere. Thanks, John> + get_page(page); > + > + copy = min_t(u32, PAGE_SIZE - offset, len - copied); > + skb_fill_page_desc(skb, i, page, offset, copy); > + > + copied += copy; > + addr += copy; > + offset = 0; > + } > + > + skb->len += len; > + skb->data_len += len; > + skb->truesize += ts; > + > + refcount_add(ts, &xs->sk.sk_wmem_alloc); > + > + return skb; > +} > +