|
@@ -1642,6 +1642,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
|
|
|
else
|
|
|
*skb_xdp = 0;
|
|
|
|
|
|
+ preempt_disable();
|
|
|
rcu_read_lock();
|
|
|
xdp_prog = rcu_dereference(tun->xdp_prog);
|
|
|
if (xdp_prog && !*skb_xdp) {
|
|
@@ -1665,6 +1666,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
|
|
|
if (err)
|
|
|
goto err_redirect;
|
|
|
rcu_read_unlock();
|
|
|
+ preempt_enable();
|
|
|
return NULL;
|
|
|
case XDP_TX:
|
|
|
xdp_xmit = true;
|
|
@@ -1686,6 +1688,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
|
|
|
skb = build_skb(buf, buflen);
|
|
|
if (!skb) {
|
|
|
rcu_read_unlock();
|
|
|
+ preempt_enable();
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
}
|
|
|
|
|
@@ -1698,10 +1701,12 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
|
|
|
skb->dev = tun->dev;
|
|
|
generic_xdp_tx(skb, xdp_prog);
|
|
|
rcu_read_unlock();
|
|
|
+ preempt_enable();
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
rcu_read_unlock();
|
|
|
+ preempt_enable();
|
|
|
|
|
|
return skb;
|
|
|
|
|
@@ -1709,6 +1714,7 @@ err_redirect:
|
|
|
put_page(alloc_frag->page);
|
|
|
err_xdp:
|
|
|
rcu_read_unlock();
|
|
|
+ preempt_enable();
|
|
|
this_cpu_inc(tun->pcpu_stats->rx_dropped);
|
|
|
return NULL;
|
|
|
}
|