ARM/ARM64: config: enable DM_INIT configuration
[platform/kernel/linux-rpi.git] / net / xfrm / xfrm_input.c
index 3df0861..3d8668d 100644 (file)
@@ -24,7 +24,8 @@
 #include "xfrm_inout.h"
 
 struct xfrm_trans_tasklet {
-       struct tasklet_struct tasklet;
+       struct work_struct work;
+       spinlock_t queue_lock;
        struct sk_buff_head queue;
 };
 
@@ -760,18 +761,22 @@ int xfrm_input_resume(struct sk_buff *skb, int nexthdr)
 }
 EXPORT_SYMBOL(xfrm_input_resume);
 
-static void xfrm_trans_reinject(struct tasklet_struct *t)
+static void xfrm_trans_reinject(struct work_struct *work)
 {
-       struct xfrm_trans_tasklet *trans = from_tasklet(trans, t, tasklet);
+       struct xfrm_trans_tasklet *trans = container_of(work, struct xfrm_trans_tasklet, work);
        struct sk_buff_head queue;
        struct sk_buff *skb;
 
        __skb_queue_head_init(&queue);
+       spin_lock_bh(&trans->queue_lock);
        skb_queue_splice_init(&trans->queue, &queue);
+       spin_unlock_bh(&trans->queue_lock);
 
+       local_bh_disable();
        while ((skb = __skb_dequeue(&queue)))
                XFRM_TRANS_SKB_CB(skb)->finish(XFRM_TRANS_SKB_CB(skb)->net,
                                               NULL, skb);
+       local_bh_enable();
 }
 
 int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
@@ -782,15 +787,17 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
 
        trans = this_cpu_ptr(&xfrm_trans_tasklet);
 
-       if (skb_queue_len(&trans->queue) >= netdev_max_backlog)
+       if (skb_queue_len(&trans->queue) >= READ_ONCE(netdev_max_backlog))
                return -ENOBUFS;
 
        BUILD_BUG_ON(sizeof(struct xfrm_trans_cb) > sizeof(skb->cb));
 
        XFRM_TRANS_SKB_CB(skb)->finish = finish;
        XFRM_TRANS_SKB_CB(skb)->net = net;
+       spin_lock_bh(&trans->queue_lock);
        __skb_queue_tail(&trans->queue, skb);
-       tasklet_schedule(&trans->tasklet);
+       spin_unlock_bh(&trans->queue_lock);
+       schedule_work(&trans->work);
        return 0;
 }
 EXPORT_SYMBOL(xfrm_trans_queue_net);
@@ -817,7 +824,8 @@ void __init xfrm_input_init(void)
                struct xfrm_trans_tasklet *trans;
 
                trans = &per_cpu(xfrm_trans_tasklet, i);
+               spin_lock_init(&trans->queue_lock);
                __skb_queue_head_init(&trans->queue);
-               tasklet_setup(&trans->tasklet, xfrm_trans_reinject);
+               INIT_WORK(&trans->work, xfrm_trans_reinject);
        }
 }