|
@@ -818,10 +818,13 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
|
|
|
skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY;
|
|
skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY;
|
|
|
skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
|
|
skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
|
|
|
}
|
|
}
|
|
|
- if (vlan)
|
|
|
|
|
|
|
+ if (vlan) {
|
|
|
|
|
+ local_bh_disable();
|
|
|
macvlan_start_xmit(skb, vlan->dev);
|
|
macvlan_start_xmit(skb, vlan->dev);
|
|
|
- else
|
|
|
|
|
|
|
+ local_bh_enable();
|
|
|
|
|
+ } else {
|
|
|
kfree_skb(skb);
|
|
kfree_skb(skb);
|
|
|
|
|
+ }
|
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
|
|
|
|
|
|
return total_len;
|
|
return total_len;
|
|
@@ -912,8 +915,11 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
|
|
|
done:
|
|
done:
|
|
|
rcu_read_lock();
|
|
rcu_read_lock();
|
|
|
vlan = rcu_dereference(q->vlan);
|
|
vlan = rcu_dereference(q->vlan);
|
|
|
- if (vlan)
|
|
|
|
|
|
|
+ if (vlan) {
|
|
|
|
|
+ preempt_disable();
|
|
|
macvlan_count_rx(vlan, copied - vnet_hdr_len, ret == 0, 0);
|
|
macvlan_count_rx(vlan, copied - vnet_hdr_len, ret == 0, 0);
|
|
|
|
|
+ preempt_enable();
|
|
|
|
|
+ }
|
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
|
|
|
|
|
|
return ret ? ret : copied;
|
|
return ret ? ret : copied;
|