Skip to content

Commit

Permalink
tuntap: tweak on the path of skb XDP case in tun_build_skb()
Browse files Browse the repository at this point in the history
If we're sure not to go native XDP, there's no need for several things
like bh and rcu stuffs. So this patch introduces a helper to build skb
and hold page refcnt. When we found we will go through skb path, build
skb directly.

Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jason Wang authored and David S. Miller committed Sep 13, 2018
1 parent f7053b6 commit ac1f1f6
Showing 1 changed file with 24 additions and 15 deletions.
39 changes: 24 additions & 15 deletions drivers/net/tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -1635,14 +1635,30 @@ static bool tun_can_build_skb(struct tun_struct *tun, struct tun_file *tfile,
return true;
}

static struct sk_buff *__tun_build_skb(struct page_frag *alloc_frag, char *buf,
int buflen, int len, int pad, int delta)
{
struct sk_buff *skb = build_skb(buf, buflen);

if (!skb)
return ERR_PTR(-ENOMEM);

skb_reserve(skb, pad - delta);
skb_put(skb, len);

get_page(alloc_frag->page);
alloc_frag->offset += buflen;

return skb;
}

static struct sk_buff *tun_build_skb(struct tun_struct *tun,
struct tun_file *tfile,
struct iov_iter *from,
struct virtio_net_hdr *hdr,
int len, int *skb_xdp)
{
struct page_frag *alloc_frag = &current->task_frag;
struct sk_buff *skb;
struct bpf_prog *xdp_prog;
int buflen = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
unsigned int delta = 0;
Expand Down Expand Up @@ -1672,10 +1688,12 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
* of xdp_prog above, this should be rare and for simplicity
* we do XDP on skb in case the headroom is not enough.
*/
if (hdr->gso_type || !xdp_prog)
if (hdr->gso_type || !xdp_prog) {
*skb_xdp = 1;
else
*skb_xdp = 0;
return __tun_build_skb(alloc_frag, buf, buflen, len, pad, delta);
}

*skb_xdp = 0;

local_bh_disable();
rcu_read_lock();
Expand Down Expand Up @@ -1719,22 +1737,13 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
trace_xdp_exception(tun->dev, xdp_prog, act);
/* fall through */
case XDP_DROP:
goto err_xdp;
goto out;
}
}
rcu_read_unlock();
local_bh_enable();

skb = build_skb(buf, buflen);
if (!skb)
return ERR_PTR(-ENOMEM);

skb_reserve(skb, pad - delta);
skb_put(skb, len);
get_page(alloc_frag->page);
alloc_frag->offset += buflen;

return skb;
return __tun_build_skb(alloc_frag, buf, buflen, len, pad, delta);

err_redirect:
put_page(alloc_frag->page);
Expand Down

0 comments on commit ac1f1f6

Please sign in to comment.