@@ -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,
@@ -789,8 +794,10 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
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);
}
}