On Thu, Aug 03, 2023 at 10:04:35PM +0800, huangjie.albert wrote: ... > +static struct sk_buff *veth_build_skb_zerocopy(struct net_device *dev, struct xsk_buff_pool *pool, > + struct xdp_desc *desc) > +{ > + struct veth_seg_info *seg_info; > + struct sk_buff *skb; > + struct page *page; > + void *hard_start; > + u32 len, ts; > + void *buffer; > + int headroom; > + u64 addr; > + u32 index; > + > + addr = desc->addr; > + len = desc->len; > + buffer = xsk_buff_raw_get_data(pool, addr); > + ts = pool->unaligned ? len : pool->chunk_size; > + > + headroom = offset_in_page(buffer); > + > + /* offset in umem pool buffer */ > + addr = buffer - pool->addrs; > + > + /* get the page of the desc */ > + page = pool->umem->pgs[addr >> PAGE_SHIFT]; > + > + /* in order to avoid to get freed by kfree_skb */ > + get_page(page); > + > + hard_start = page_to_virt(page); > + > + skb = veth_build_skb(hard_start, headroom, len, ts); > + seg_info = (struct veth_seg_info *)kmalloc(struct_size(seg_info, desc, MAX_SKB_FRAGS), GFP_KERNEL); There is no need to explicitly case the return value of kmalloc, as it returns void *. seg_info = kmalloc(struct_size(seg_info, desc, MAX_SKB_FRAGS), GFP_KERNEL); ...