* [Patch]net/xfrm/xfrm_policy.c: replace timer with delayed_work @ 2008-02-16 15:55 WANG Cong 2008-04-27 1:18 ` Herbert Xu 0 siblings, 1 reply; 17+ messages in thread From: WANG Cong @ 2008-02-16 15:55 UTC (permalink / raw) To: Linux Kernel Mailing List; +Cc: Herbert Xu, David Miller, Andrew Morton, netdev As suggested by Herbert, using workqueue is better than timer for net/xfrm/xfrm_policy.c, so replace them with delayed_work. Note that, this patch is not fully tested, just compile and run as a whole on an Intel Core Duo matchine. So should be in -mm first. Signed-off-by: WANG Cong <xiyou.wangcong@gmail.com> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: David Miller <davem@davemloft.net> --- diff --git a/include/net/xfrm.h b/include/net/xfrm.h index ac72116..53f4794 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -430,7 +430,7 @@ struct xfrm_policy /* This lock only affects elements except for entry. */ rwlock_t lock; atomic_t refcnt; - struct timer_list timer; + struct delayed_work work; u32 priority; u32 index; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 47219f9..58066f0 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -126,9 +126,10 @@ static inline unsigned long make_jiffies(long secs) return secs*HZ; } -static void xfrm_policy_timer(unsigned long data) +static void xfrm_policy_worker(struct work_struct *w) { - struct xfrm_policy *xp = (struct xfrm_policy*)data; + struct xfrm_policy *xp = + container_of((struct delayed_work *)w, struct xfrm_policy, work); unsigned long now = get_seconds(); long next = LONG_MAX; int warn = 0; @@ -181,7 +182,7 @@ static void xfrm_policy_timer(unsigned long data) if (warn) km_policy_expired(xp, dir, 0, 0); if (next != LONG_MAX && - !mod_timer(&xp->timer, jiffies + make_jiffies(next))) + !schedule_delayed_work(&xp->work, make_jiffies(next))) xfrm_pol_hold(xp); out: @@ -208,12 +209,11 @@ struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp) policy = kzalloc(sizeof(struct xfrm_policy), gfp); if (policy) { + INIT_DELAYED_WORK(&policy->work, xfrm_policy_worker); INIT_HLIST_NODE(&policy->bydst); INIT_HLIST_NODE(&policy->byidx); rwlock_init(&policy->lock); atomic_set(&policy->refcnt, 1); - setup_timer(&policy->timer, xfrm_policy_timer, - (unsigned long)policy); } return policy; } @@ -227,7 +227,7 @@ void xfrm_policy_destroy(struct xfrm_policy *policy) BUG_ON(policy->bundles); - if (del_timer(&policy->timer)) + if (cancel_delayed_work(&policy->work)) BUG(); security_xfrm_policy_free(policy); @@ -244,7 +244,7 @@ static void xfrm_policy_gc_kill(struct xfrm_policy *policy) dst_free(dst); } - if (del_timer(&policy->timer)) + if (cancel_delayed_work(&policy->work)) atomic_dec(&policy->refcnt); if (atomic_read(&policy->refcnt) > 1) @@ -566,7 +566,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) hlist_add_head(&policy->byidx, xfrm_policy_byidx+idx_hash(policy->index)); policy->curlft.add_time = get_seconds(); policy->curlft.use_time = 0; - if (!mod_timer(&policy->timer, jiffies + HZ)) + if (!schedule_delayed_work(&policy->work, HZ)) xfrm_pol_hold(policy); write_unlock_bh(&xfrm_policy_lock); ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [Patch]net/xfrm/xfrm_policy.c: replace timer with delayed_work 2008-02-16 15:55 [Patch]net/xfrm/xfrm_policy.c: replace timer with delayed_work WANG Cong @ 2008-04-27 1:18 ` Herbert Xu 2008-04-28 14:53 ` WANG Cong 0 siblings, 1 reply; 17+ messages in thread From: Herbert Xu @ 2008-04-27 1:18 UTC (permalink / raw) To: WANG Cong; +Cc: Linux Kernel Mailing List, David Miller, Andrew Morton, netdev On Sat, Feb 16, 2008 at 11:55:34PM +0800, WANG Cong wrote: > > As suggested by Herbert, using workqueue is better than timer > for net/xfrm/xfrm_policy.c, so replace them with delayed_work. > > Note that, this patch is not fully tested, just compile and > run as a whole on an Intel Core Duo matchine. So should be > in -mm first. > > Signed-off-by: WANG Cong <xiyou.wangcong@gmail.com> > Cc: Herbert Xu <herbert@gondor.apana.org.au> > Cc: David Miller <davem@davemloft.net> Sorry for the extremely long delay, but I've finally made it to this email in my backlog :) The patch looks OK except for one thing, the read-write spin lock needs to disable BH now that it's moved to process context. Otherwise we'll get dead-locks with the softirq path taking the same lock. Thanks, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Patch]net/xfrm/xfrm_policy.c: replace timer with delayed_work 2008-04-27 1:18 ` Herbert Xu @ 2008-04-28 14:53 ` WANG Cong 2008-04-28 15:13 ` Herbert Xu 0 siblings, 1 reply; 17+ messages in thread From: WANG Cong @ 2008-04-28 14:53 UTC (permalink / raw) To: herbert; +Cc: linux-kernel, davem, akpm, netdev From: Herbert Xu <herbert@gondor.apana.org.au> Date: Sun, 27 Apr 2008 09:18:09 +0800 > On Sat, Feb 16, 2008 at 11:55:34PM +0800, WANG Cong wrote: > > > > As suggested by Herbert, using workqueue is better than timer > > for net/xfrm/xfrm_policy.c, so replace them with delayed_work. > > > > Note that, this patch is not fully tested, just compile and > > run as a whole on an Intel Core Duo matchine. So should be > > in -mm first. > > > > Signed-off-by: WANG Cong <xiyou.wangcong@gmail.com> > > Cc: Herbert Xu <herbert@gondor.apana.org.au> > > Cc: David Miller <davem@davemloft.net> > > Sorry for the extremely long delay, but I've finally made it > to this email in my backlog :) > > The patch looks OK except for one thing, the read-write spin > lock needs to disable BH now that it's moved to process context. > Otherwise we'll get dead-locks with the softirq path taking the > same lock. Do you mean ->lock of struct xfrm_policy? OK. I will recook these two patches soon. Thanks for review. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Patch]net/xfrm/xfrm_policy.c: replace timer with delayed_work 2008-04-28 14:53 ` WANG Cong @ 2008-04-28 15:13 ` Herbert Xu 2008-04-30 16:06 ` WANG Cong 0 siblings, 1 reply; 17+ messages in thread From: Herbert Xu @ 2008-04-28 15:13 UTC (permalink / raw) To: WANG Cong; +Cc: linux-kernel, davem, akpm, netdev On Mon, Apr 28, 2008 at 10:53:12PM +0800, WANG Cong wrote: > > Do you mean ->lock of struct xfrm_policy? > OK. I will recook these two patches soon. Yep. Thanks, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Patch]net/xfrm/xfrm_policy.c: replace timer with delayed_work 2008-04-28 15:13 ` Herbert Xu @ 2008-04-30 16:06 ` WANG Cong 2008-05-01 1:11 ` Herbert Xu 0 siblings, 1 reply; 17+ messages in thread From: WANG Cong @ 2008-04-30 16:06 UTC (permalink / raw) To: Herbert Xu; +Cc: WANG Cong, linux-kernel, davem, akpm, netdev On Mon, 28 Apr 2008, Herbert Xu wrote: > On Mon, Apr 28, 2008 at 10:53:12PM +0800, WANG Cong wrote: >> >> Do you mean ->lock of struct xfrm_policy? >> OK. I will recook these two patches soon. > > Yep. Hi, Herbert. I referenced the book Linux Device Drivers, it is said that the work function in workqueue can sleep, that is to say, it only works in process context, so we don't need the disable the lock in softirq, which is interrupt context, right? Please teach me if I missed some obvious things. ;-) Thanks. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Patch]net/xfrm/xfrm_policy.c: replace timer with delayed_work 2008-04-30 16:06 ` WANG Cong @ 2008-05-01 1:11 ` Herbert Xu 2008-05-02 5:21 ` WANG Cong ` (2 more replies) 0 siblings, 3 replies; 17+ messages in thread From: Herbert Xu @ 2008-05-01 1:11 UTC (permalink / raw) To: WANG Cong; +Cc: linux-kernel, davem, akpm, netdev On Thu, May 01, 2008 at 12:06:55AM +0800, WANG Cong wrote: > > Hi, Herbert. > > I referenced the book Linux Device Drivers, it is said that > the work function in workqueue can sleep, that is to say, it only > works in process context, so we don't need the disable the lock > in softirq, which is interrupt context, right? Because it can sleep, you must disable BH for locks that can be taken on the softirq path as otherwise a softirq can come in, try to take the lock again and dead-lock. Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Patch]net/xfrm/xfrm_policy.c: replace timer with delayed_work 2008-05-01 1:11 ` Herbert Xu @ 2008-05-02 5:21 ` WANG Cong 2008-05-02 5:35 ` [Patch] (revised) net/xfrm/xfrm_policy.c: " WANG Cong 2008-05-02 5:43 ` [Patch](Revised) net/xfrm/xfrm_state.c: " WANG Cong 2 siblings, 0 replies; 17+ messages in thread From: WANG Cong @ 2008-05-02 5:21 UTC (permalink / raw) To: Herbert Xu; +Cc: WANG Cong, linux-kernel, davem, akpm, netdev On Thu, 1 May 2008, Herbert Xu wrote: > On Thu, May 01, 2008 at 12:06:55AM +0800, WANG Cong wrote: >> >> Hi, Herbert. >> >> I referenced the book Linux Device Drivers, it is said that >> the work function in workqueue can sleep, that is to say, it only >> works in process context, so we don't need the disable the lock >> in softirq, which is interrupt context, right? > > Because it can sleep, you must disable BH for locks that can > be taken on the softirq path as otherwise a softirq can come > in, try to take the lock again and dead-lock. Yes, I was an idiot. I will resend the revised patches right now. ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Patch] (revised) net/xfrm/xfrm_policy.c: replace timer with delayed_work 2008-05-01 1:11 ` Herbert Xu 2008-05-02 5:21 ` WANG Cong @ 2008-05-02 5:35 ` WANG Cong 2008-05-02 23:54 ` David Miller 2008-05-06 3:08 ` Herbert Xu 2008-05-02 5:43 ` [Patch](Revised) net/xfrm/xfrm_state.c: " WANG Cong 2 siblings, 2 replies; 17+ messages in thread From: WANG Cong @ 2008-05-02 5:35 UTC (permalink / raw) To: Herbert Xu; +Cc: WANG Cong, linux-kernel, davem, akpm, netdev As suggested by Herbert Xu, using workqueue is better than timer for net/xfrm/xfrm_policy.c, so replace them with delayed_work. And due to this change, we have to disable BH when trying to lock. Note that, this patch is not fully tested, so should be in -mm first. Signed-off-by: WANG Cong <wangcong@zeuux.org> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: David Miller <davem@davemloft.net> diff --git a/include/net/xfrm.h b/include/net/xfrm.h index d1350bc..ba1bb24 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -457,7 +457,7 @@ struct xfrm_policy /* This lock only affects elements except for entry. */ rwlock_t lock; atomic_t refcnt; - struct timer_list timer; + struct delayed_work work; u32 priority; u32 index; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index cae9fd8..2ed14e0 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -154,15 +154,16 @@ static inline unsigned long make_jiffies(long secs) return secs*HZ; } -static void xfrm_policy_timer(unsigned long data) +static void xfrm_policy_worker(struct work_struct *w) { - struct xfrm_policy *xp = (struct xfrm_policy*)data; + struct xfrm_policy *xp = + container_of((struct delayed_work *)w, struct xfrm_policy, work); unsigned long now = get_seconds(); long next = LONG_MAX; int warn = 0; int dir; - read_lock(&xp->lock); + read_lock_bh(&xp->lock); if (xp->dead) goto out; @@ -209,16 +210,16 @@ static void xfrm_policy_timer(unsigned long data) if (warn) km_policy_expired(xp, dir, 0, 0); if (next != LONG_MAX && - !mod_timer(&xp->timer, jiffies + make_jiffies(next))) + !schedule_delayed_work(&xp->work, make_jiffies(next))) xfrm_pol_hold(xp); out: - read_unlock(&xp->lock); + read_unlock_bh(&xp->lock); xfrm_pol_put(xp); return; expired: - read_unlock(&xp->lock); + read_unlock_bh(&xp->lock); if (!xfrm_policy_delete(xp, dir)) km_policy_expired(xp, dir, 1, 0); xfrm_pol_put(xp); @@ -236,13 +237,12 @@ struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp) policy = kzalloc(sizeof(struct xfrm_policy), gfp); if (policy) { + INIT_DELAYED_WORK(&policy->work, xfrm_policy_worker); INIT_LIST_HEAD(&policy->bytype); INIT_HLIST_NODE(&policy->bydst); INIT_HLIST_NODE(&policy->byidx); rwlock_init(&policy->lock); atomic_set(&policy->refcnt, 1); - setup_timer(&policy->timer, xfrm_policy_timer, - (unsigned long)policy); } return policy; } @@ -256,7 +256,7 @@ void xfrm_policy_destroy(struct xfrm_policy *policy) BUG_ON(policy->bundles); - if (del_timer(&policy->timer)) + if (cancel_delayed_work(&policy->work)) BUG(); write_lock_bh(&xfrm_policy_lock); @@ -277,7 +277,7 @@ static void xfrm_policy_gc_kill(struct xfrm_policy *policy) dst_free(dst); } - if (del_timer(&policy->timer)) + if (cancel_delayed_work(&policy->work)) atomic_dec(&policy->refcnt); if (atomic_read(&policy->refcnt) > 1) @@ -615,7 +615,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) hlist_add_head(&policy->byidx, xfrm_policy_byidx+idx_hash(policy->index)); policy->curlft.add_time = get_seconds(); policy->curlft.use_time = 0; - if (!mod_timer(&policy->timer, jiffies + HZ)) + if (!schedule_delayed_work(&policy->work, HZ)) xfrm_pol_hold(policy); list_add_tail(&policy->bytype, &xfrm_policy_bytype[policy->type]); write_unlock_bh(&xfrm_policy_lock); ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [Patch] (revised) net/xfrm/xfrm_policy.c: replace timer with delayed_work 2008-05-02 5:35 ` [Patch] (revised) net/xfrm/xfrm_policy.c: " WANG Cong @ 2008-05-02 23:54 ` David Miller 2008-05-03 14:46 ` WANG Cong 2008-05-06 3:08 ` Herbert Xu 1 sibling, 1 reply; 17+ messages in thread From: David Miller @ 2008-05-02 23:54 UTC (permalink / raw) To: xiyou.wangcong; +Cc: herbert, linux-kernel, akpm, netdev From: WANG Cong <xiyou.wangcong@gmail.com> Date: Fri, 2 May 2008 13:35:55 +0800 (CST) > > As suggested by Herbert Xu, using workqueue is better than timer > for net/xfrm/xfrm_policy.c, so replace them with delayed_work. > And due to this change, we have to disable BH when trying to > lock. > > Note that, this patch is not fully tested, so should be > in -mm first. > > Signed-off-by: WANG Cong <wangcong@zeuux.org> Please let me know when these two patches have gotten some good testing. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Patch] (revised) net/xfrm/xfrm_policy.c: replace timer with delayed_work 2008-05-02 23:54 ` David Miller @ 2008-05-03 14:46 ` WANG Cong 2008-05-03 15:06 ` Herbert Xu 2008-05-04 1:37 ` David Miller 0 siblings, 2 replies; 17+ messages in thread From: WANG Cong @ 2008-05-03 14:46 UTC (permalink / raw) To: David Miller; +Cc: xiyou.wangcong, herbert, linux-kernel, akpm, netdev On Fri, May 02, 2008 at 04:54:55PM -0700, David Miller wrote: >From: WANG Cong <xiyou.wangcong@gmail.com> >Date: Fri, 2 May 2008 13:35:55 +0800 (CST) > >> >> As suggested by Herbert Xu, using workqueue is better than timer >> for net/xfrm/xfrm_policy.c, so replace them with delayed_work. >> And due to this change, we have to disable BH when trying to >> lock. >> >> Note that, this patch is not fully tested, so should be >> in -mm first. >> >> Signed-off-by: WANG Cong <wangcong@zeuux.org> > >Please let me know when these two patches have gotten some >good testing. Thanks for your comments, David! I thought it can go into -mm so that many other people can help me to test it. Since I didn't have the IPSec environment. ;( I will try if I can set up one, then test it. Thanks. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Patch] (revised) net/xfrm/xfrm_policy.c: replace timer with delayed_work 2008-05-03 14:46 ` WANG Cong @ 2008-05-03 15:06 ` Herbert Xu 2008-05-03 15:31 ` WANG Cong 2008-05-04 1:38 ` David Miller 2008-05-04 1:37 ` David Miller 1 sibling, 2 replies; 17+ messages in thread From: Herbert Xu @ 2008-05-03 15:06 UTC (permalink / raw) To: WANG Cong; +Cc: David Miller, linux-kernel, akpm, netdev On Sat, May 03, 2008 at 10:46:49PM +0800, WANG Cong wrote: > > I will try if I can set up one, then test it. I'll throw them into my test systems here and see if they break. Thanks, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Patch] (revised) net/xfrm/xfrm_policy.c: replace timer with delayed_work 2008-05-03 15:06 ` Herbert Xu @ 2008-05-03 15:31 ` WANG Cong 2008-05-04 1:38 ` David Miller 1 sibling, 0 replies; 17+ messages in thread From: WANG Cong @ 2008-05-03 15:31 UTC (permalink / raw) To: Herbert Xu; +Cc: WANG Cong, David Miller, linux-kernel, akpm, netdev On Sat, May 03, 2008 at 11:06:06PM +0800, Herbert Xu wrote: >On Sat, May 03, 2008 at 10:46:49PM +0800, WANG Cong wrote: >> >> I will try if I can set up one, then test it. > >I'll throw them into my test systems here and see if they break. > Oh, thanks a lot! ;-) ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Patch] (revised) net/xfrm/xfrm_policy.c: replace timer with delayed_work 2008-05-03 15:06 ` Herbert Xu 2008-05-03 15:31 ` WANG Cong @ 2008-05-04 1:38 ` David Miller 1 sibling, 0 replies; 17+ messages in thread From: David Miller @ 2008-05-04 1:38 UTC (permalink / raw) To: herbert; +Cc: xiyou.wangcong, linux-kernel, akpm, netdev From: Herbert Xu <herbert@gondor.apana.org.au> Date: Sat, 3 May 2008 23:06:06 +0800 > On Sat, May 03, 2008 at 10:46:49PM +0800, WANG Cong wrote: > > > > I will try if I can set up one, then test it. > > I'll throw them into my test systems here and see if they break. Thanks Herbert. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Patch] (revised) net/xfrm/xfrm_policy.c: replace timer with delayed_work 2008-05-03 14:46 ` WANG Cong 2008-05-03 15:06 ` Herbert Xu @ 2008-05-04 1:37 ` David Miller 1 sibling, 0 replies; 17+ messages in thread From: David Miller @ 2008-05-04 1:37 UTC (permalink / raw) To: xiyou.wangcong; +Cc: herbert, linux-kernel, akpm, netdev From: WANG Cong <xiyou.wangcong@gmail.com> Date: Sat, 3 May 2008 22:46:49 +0800 > I thought it can go into -mm so that many other people can help > me to test it. Since I didn't have the IPSec environment. ;( You don't need an "IPSEC environment" (whatever that is) to test these code paths. It's very easy to setup simplistic IPSEC states and policies between two computers using "setkey" and friends. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Patch] (revised) net/xfrm/xfrm_policy.c: replace timer with delayed_work 2008-05-02 5:35 ` [Patch] (revised) net/xfrm/xfrm_policy.c: " WANG Cong 2008-05-02 23:54 ` David Miller @ 2008-05-06 3:08 ` Herbert Xu 2008-05-06 3:57 ` WANG Cong 1 sibling, 1 reply; 17+ messages in thread From: Herbert Xu @ 2008-05-06 3:08 UTC (permalink / raw) To: WANG Cong; +Cc: linux-kernel, davem, akpm, netdev On Fri, May 02, 2008 at 01:35:55PM +0800, WANG Cong wrote: > > @@ -209,16 +210,16 @@ static void xfrm_policy_timer(unsigned long data) > if (warn) > km_policy_expired(xp, dir, 0, 0); > if (next != LONG_MAX && > - !mod_timer(&xp->timer, jiffies + make_jiffies(next))) > + !schedule_delayed_work(&xp->work, make_jiffies(next))) > xfrm_pol_hold(xp); I tried it and it pretty much crashed immediately :) The problem is that schedule_delayed_work's return value is the opposite of mod_timer. So you'll need to reverse the tests. Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Patch] (revised) net/xfrm/xfrm_policy.c: replace timer with delayed_work 2008-05-06 3:08 ` Herbert Xu @ 2008-05-06 3:57 ` WANG Cong 0 siblings, 0 replies; 17+ messages in thread From: WANG Cong @ 2008-05-06 3:57 UTC (permalink / raw) To: Herbert Xu; +Cc: WANG Cong, linux-kernel, davem, akpm, netdev [-- Attachment #1: Type: text/plain, Size: 1027 bytes --] On Tue, May 06, 2008 at 11:08:22AM +0800, Herbert Xu wrote: >On Fri, May 02, 2008 at 01:35:55PM +0800, WANG Cong wrote: >> >> @@ -209,16 +210,16 @@ static void xfrm_policy_timer(unsigned long data) >> if (warn) >> km_policy_expired(xp, dir, 0, 0); >> if (next != LONG_MAX && >> - !mod_timer(&xp->timer, jiffies + make_jiffies(next))) >> + !schedule_delayed_work(&xp->work, make_jiffies(next))) >> xfrm_pol_hold(xp); > >I tried it and it pretty much crashed immediately :) > >The problem is that schedule_delayed_work's return value is the >opposite of mod_timer. So you'll need to reverse the tests. I apologize. mod_timer() returns 0 if the timer is pending, schedule_delayed_work() returns 0 when the work is on the queue. Oh, yes, you're correct!! It's my fault. And I recheck the source code. I find del_timer() and cancel_delayed_work() which I also worried about has no such problem. So just reverse the check for schedule_delayed_work(). Thanks for your kind help! Updated patches are attached. [-- Attachment #2: policy.diff --] [-- Type: text/plain, Size: 3004 bytes --] diff --git a/include/net/xfrm.h b/include/net/xfrm.h index d1350bc..ba1bb24 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -457,7 +457,7 @@ struct xfrm_policy /* This lock only affects elements except for entry. */ rwlock_t lock; atomic_t refcnt; - struct timer_list timer; + struct delayed_work work; u32 priority; u32 index; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index cae9fd8..2ed14e0 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -154,15 +154,16 @@ static inline unsigned long make_jiffies(long secs) return secs*HZ; } -static void xfrm_policy_timer(unsigned long data) +static void xfrm_policy_worker(struct work_struct *w) { - struct xfrm_policy *xp = (struct xfrm_policy*)data; + struct xfrm_policy *xp = + container_of((struct delayed_work *)w, struct xfrm_policy, work); unsigned long now = get_seconds(); long next = LONG_MAX; int warn = 0; int dir; - read_lock(&xp->lock); + read_lock_bh(&xp->lock); if (xp->dead) goto out; @@ -209,16 +210,16 @@ static void xfrm_policy_timer(unsigned long data) if (warn) km_policy_expired(xp, dir, 0, 0); if (next != LONG_MAX && - !mod_timer(&xp->timer, jiffies + make_jiffies(next))) + schedule_delayed_work(&xp->work, make_jiffies(next))) xfrm_pol_hold(xp); out: - read_unlock(&xp->lock); + read_unlock_bh(&xp->lock); xfrm_pol_put(xp); return; expired: - read_unlock(&xp->lock); + read_unlock_bh(&xp->lock); if (!xfrm_policy_delete(xp, dir)) km_policy_expired(xp, dir, 1, 0); xfrm_pol_put(xp); @@ -236,13 +237,12 @@ struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp) policy = kzalloc(sizeof(struct xfrm_policy), gfp); if (policy) { + INIT_DELAYED_WORK(&policy->work, xfrm_policy_worker); INIT_LIST_HEAD(&policy->bytype); INIT_HLIST_NODE(&policy->bydst); INIT_HLIST_NODE(&policy->byidx); rwlock_init(&policy->lock); atomic_set(&policy->refcnt, 1); - setup_timer(&policy->timer, xfrm_policy_timer, - (unsigned long)policy); } return policy; } @@ -256,7 +256,7 @@ void xfrm_policy_destroy(struct xfrm_policy *policy) BUG_ON(policy->bundles); - if (del_timer(&policy->timer)) + if (cancel_delayed_work(&policy->work)) BUG(); write_lock_bh(&xfrm_policy_lock); @@ -277,7 +277,7 @@ static void xfrm_policy_gc_kill(struct xfrm_policy *policy) dst_free(dst); } - if (del_timer(&policy->timer)) + if (cancel_delayed_work(&policy->work)) atomic_dec(&policy->refcnt); if (atomic_read(&policy->refcnt) > 1) @@ -615,7 +615,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) hlist_add_head(&policy->byidx, xfrm_policy_byidx+idx_hash(policy->index)); policy->curlft.add_time = get_seconds(); policy->curlft.use_time = 0; - if (!mod_timer(&policy->timer, jiffies + HZ)) + if (schedule_delayed_work(&policy->work, HZ)) xfrm_pol_hold(policy); list_add_tail(&policy->bytype, &xfrm_policy_bytype[policy->type]); write_unlock_bh(&xfrm_policy_lock); [-- Attachment #3: state.diff --] [-- Type: text/plain, Size: 8351 bytes --] diff --git a/include/net/xfrm.h b/include/net/xfrm.h index d1350bc..539dccd 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -189,14 +189,14 @@ struct xfrm_state u32 replay_maxage; u32 replay_maxdiff; - /* Replay detection notification timer */ - struct timer_list rtimer; + /* Replay detection notification delayed work */ + struct delayed_work rwork; /* Statistics */ struct xfrm_stats stats; struct xfrm_lifetime_cur curlft; - struct timer_list timer; + struct delayed_work work; /* Last used time */ unsigned long lastused; @@ -457,7 +457,7 @@ struct xfrm_policy /* This lock only affects elements except for entry. */ rwlock_t lock; atomic_t refcnt; - struct timer_list timer; + struct delayed_work work; u32 priority; u32 index; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index cae9fd8..2ed14e0 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -154,15 +154,16 @@ static inline unsigned long make_jiffies(long secs) return secs*HZ; } -static void xfrm_policy_timer(unsigned long data) +static void xfrm_policy_worker(struct work_struct *w) { - struct xfrm_policy *xp = (struct xfrm_policy*)data; + struct xfrm_policy *xp = + container_of((struct delayed_work *)w, struct xfrm_policy, work); unsigned long now = get_seconds(); long next = LONG_MAX; int warn = 0; int dir; - read_lock(&xp->lock); + read_lock_bh(&xp->lock); if (xp->dead) goto out; @@ -209,16 +210,16 @@ static void xfrm_policy_timer(unsigned long data) if (warn) km_policy_expired(xp, dir, 0, 0); if (next != LONG_MAX && - !mod_timer(&xp->timer, jiffies + make_jiffies(next))) + schedule_delayed_work(&xp->work, make_jiffies(next))) xfrm_pol_hold(xp); out: - read_unlock(&xp->lock); + read_unlock_bh(&xp->lock); xfrm_pol_put(xp); return; expired: - read_unlock(&xp->lock); + read_unlock_bh(&xp->lock); if (!xfrm_policy_delete(xp, dir)) km_policy_expired(xp, dir, 1, 0); xfrm_pol_put(xp); @@ -236,13 +237,12 @@ struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp) policy = kzalloc(sizeof(struct xfrm_policy), gfp); if (policy) { + INIT_DELAYED_WORK(&policy->work, xfrm_policy_worker); INIT_LIST_HEAD(&policy->bytype); INIT_HLIST_NODE(&policy->bydst); INIT_HLIST_NODE(&policy->byidx); rwlock_init(&policy->lock); atomic_set(&policy->refcnt, 1); - setup_timer(&policy->timer, xfrm_policy_timer, - (unsigned long)policy); } return policy; } @@ -256,7 +256,7 @@ void xfrm_policy_destroy(struct xfrm_policy *policy) BUG_ON(policy->bundles); - if (del_timer(&policy->timer)) + if (cancel_delayed_work(&policy->work)) BUG(); write_lock_bh(&xfrm_policy_lock); @@ -277,7 +277,7 @@ static void xfrm_policy_gc_kill(struct xfrm_policy *policy) dst_free(dst); } - if (del_timer(&policy->timer)) + if (cancel_delayed_work(&policy->work)) atomic_dec(&policy->refcnt); if (atomic_read(&policy->refcnt) > 1) @@ -615,7 +615,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) hlist_add_head(&policy->byidx, xfrm_policy_byidx+idx_hash(policy->index)); policy->curlft.add_time = get_seconds(); policy->curlft.use_time = 0; - if (!mod_timer(&policy->timer, jiffies + HZ)) + if (schedule_delayed_work(&policy->work, HZ)) xfrm_pol_hold(policy); list_add_tail(&policy->bytype, &xfrm_policy_bytype[policy->type]); write_unlock_bh(&xfrm_policy_lock); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 72fddaf..b384d81 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -380,8 +380,8 @@ static void xfrm_put_mode(struct xfrm_mode *mode) static void xfrm_state_gc_destroy(struct xfrm_state *x) { - del_timer_sync(&x->timer); - del_timer_sync(&x->rtimer); + cancel_delayed_work_sync(&x->work); + cancel_delayed_work_sync(&x->rwork); kfree(x->aalg); kfree(x->ealg); kfree(x->calg); @@ -426,15 +426,16 @@ static inline unsigned long make_jiffies(long secs) return secs*HZ; } -static void xfrm_timer_handler(unsigned long data) +static void xfrm_work_handler(struct work_struct *w) { - struct xfrm_state *x = (struct xfrm_state*)data; + struct xfrm_state *x = + container_of((struct delayed_work *)w, struct xfrm_state, work); unsigned long now = get_seconds(); long next = LONG_MAX; int warn = 0; int err = 0; - spin_lock(&x->lock); + spin_lock_bh(&x->lock); if (x->km.state == XFRM_STATE_DEAD) goto out; if (x->km.state == XFRM_STATE_EXPIRED) @@ -479,7 +480,7 @@ static void xfrm_timer_handler(unsigned long data) km_state_expired(x, 0, 0); resched: if (next != LONG_MAX) - mod_timer(&x->timer, jiffies + make_jiffies(next)); + schedule_delayed_work(&x->work, make_jiffies(next)); goto out; @@ -500,10 +501,10 @@ expired: audit_get_sessionid(current), 0); out: - spin_unlock(&x->lock); + spin_unlock_bh(&x->lock); } -static void xfrm_replay_timer_handler(unsigned long data); +static void xfrm_replay_work_handler(struct work_struct *); struct xfrm_state *xfrm_state_alloc(void) { @@ -518,9 +519,8 @@ struct xfrm_state *xfrm_state_alloc(void) INIT_HLIST_NODE(&x->bydst); INIT_HLIST_NODE(&x->bysrc); INIT_HLIST_NODE(&x->byspi); - setup_timer(&x->timer, xfrm_timer_handler, (unsigned long)x); - setup_timer(&x->rtimer, xfrm_replay_timer_handler, - (unsigned long)x); + INIT_DELAYED_WORK(&x->work, xfrm_work_handler); + INIT_DELAYED_WORK(&x->rwork, xfrm_replay_work_handler); x->curlft.add_time = get_seconds(); x->lft.soft_byte_limit = XFRM_INF; x->lft.soft_packet_limit = XFRM_INF; @@ -864,8 +864,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, hlist_add_head(&x->byspi, xfrm_state_byspi+h); } x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires; - x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; - add_timer(&x->timer); + schedule_delayed_work(&x->work, sysctl_xfrm_acq_expires*HZ); xfrm_state_num++; xfrm_hash_grow_check(x->bydst.next != NULL); } else { @@ -938,9 +937,9 @@ static void __xfrm_state_insert(struct xfrm_state *x) hlist_add_head(&x->byspi, xfrm_state_byspi+h); } - mod_timer(&x->timer, jiffies + HZ); + schedule_delayed_work(&x->work, HZ); if (x->replay_maxage) - mod_timer(&x->rtimer, jiffies + x->replay_maxage); + schedule_delayed_work(&x->rwork, x->replay_maxage); wake_up(&km_waitq); @@ -1049,8 +1048,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re x->props.reqid = reqid; x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires; xfrm_state_hold(x); - x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; - add_timer(&x->timer); + schedule_delayed_work(&x->work, sysctl_xfrm_acq_expires*HZ); hlist_add_head(&x->bydst, xfrm_state_bydst+h); h = xfrm_src_hash(daddr, saddr, family); hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); @@ -1317,7 +1315,7 @@ out: memcpy(&x1->lft, &x->lft, sizeof(x1->lft)); x1->km.dying = 0; - mod_timer(&x1->timer, jiffies + HZ); + schedule_delayed_work(&x1->work, HZ); if (x1->curlft.use_time) xfrm_state_check_expire(x1); @@ -1342,7 +1340,7 @@ int xfrm_state_check_expire(struct xfrm_state *x) if (x->curlft.bytes >= x->lft.hard_byte_limit || x->curlft.packets >= x->lft.hard_packet_limit) { x->km.state = XFRM_STATE_EXPIRED; - mod_timer(&x->timer, jiffies); + schedule_delayed_work(&x->work, 0); return -EINVAL; } @@ -1622,15 +1620,16 @@ void xfrm_replay_notify(struct xfrm_state *x, int event) km_state_notify(x, &c); if (x->replay_maxage && - !mod_timer(&x->rtimer, jiffies + x->replay_maxage)) + schedule_delayed_work(&x->rwork, x->replay_maxage)) x->xflags &= ~XFRM_TIME_DEFER; } -static void xfrm_replay_timer_handler(unsigned long data) +static void xfrm_replay_work_handler(struct work_struct *w) { - struct xfrm_state *x = (struct xfrm_state*)data; + struct xfrm_state *x = + container_of((struct delayed_work *)w, struct xfrm_state, rwork); - spin_lock(&x->lock); + spin_lock_bh(&x->lock); if (x->km.state == XFRM_STATE_VALID) { if (xfrm_aevent_is_on()) @@ -1639,7 +1638,7 @@ static void xfrm_replay_timer_handler(unsigned long data) x->xflags |= XFRM_TIME_DEFER; } - spin_unlock(&x->lock); + spin_unlock_bh(&x->lock); } int xfrm_replay_check(struct xfrm_state *x, ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Patch](Revised) net/xfrm/xfrm_state.c: replace timer with delayed_work 2008-05-01 1:11 ` Herbert Xu 2008-05-02 5:21 ` WANG Cong 2008-05-02 5:35 ` [Patch] (revised) net/xfrm/xfrm_policy.c: " WANG Cong @ 2008-05-02 5:43 ` WANG Cong 2 siblings, 0 replies; 17+ messages in thread From: WANG Cong @ 2008-05-02 5:43 UTC (permalink / raw) To: Herbert Xu; +Cc: WANG Cong, linux-kernel, davem, akpm, netdev Also suggested by Herbert Xu, using workqueue is better than timers for net/xfrm/xfrm_state.c, so replace them with delayed_work. And due to this change, we have to disable BH when trying to lock. Note that, this patch is not fully tested. So should be in -mm first. Signed-off-by: WANG Cong <wangcong@zeuux.org> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: David Miller <davem@davemloft.net> --- diff --git a/include/net/xfrm.h b/include/net/xfrm.h index d1350bc..539dccd 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -189,14 +189,14 @@ struct xfrm_state u32 replay_maxage; u32 replay_maxdiff; - /* Replay detection notification timer */ - struct timer_list rtimer; + /* Replay detection notification delayed work */ + struct delayed_work rwork; /* Statistics */ struct xfrm_stats stats; struct xfrm_lifetime_cur curlft; - struct timer_list timer; + struct delayed_work work; /* Last used time */ unsigned long lastused; @@ -457,7 +457,7 @@ struct xfrm_policy /* This lock only affects elements except for entry. */ rwlock_t lock; atomic_t refcnt; - struct timer_list timer; + struct delayed_work work; u32 priority; u32 index; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index cae9fd8..2ed14e0 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -154,15 +154,16 @@ static inline unsigned long make_jiffies(long secs) return secs*HZ; } -static void xfrm_policy_timer(unsigned long data) +static void xfrm_policy_worker(struct work_struct *w) { - struct xfrm_policy *xp = (struct xfrm_policy*)data; + struct xfrm_policy *xp = + container_of((struct delayed_work *)w, struct xfrm_policy, work); unsigned long now = get_seconds(); long next = LONG_MAX; int warn = 0; int dir; - read_lock(&xp->lock); + read_lock_bh(&xp->lock); if (xp->dead) goto out; @@ -209,16 +210,16 @@ static void xfrm_policy_timer(unsigned long data) if (warn) km_policy_expired(xp, dir, 0, 0); if (next != LONG_MAX && - !mod_timer(&xp->timer, jiffies + make_jiffies(next))) + !schedule_delayed_work(&xp->work, make_jiffies(next))) xfrm_pol_hold(xp); out: - read_unlock(&xp->lock); + read_unlock_bh(&xp->lock); xfrm_pol_put(xp); return; expired: - read_unlock(&xp->lock); + read_unlock_bh(&xp->lock); if (!xfrm_policy_delete(xp, dir)) km_policy_expired(xp, dir, 1, 0); xfrm_pol_put(xp); @@ -236,13 +237,12 @@ struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp) policy = kzalloc(sizeof(struct xfrm_policy), gfp); if (policy) { + INIT_DELAYED_WORK(&policy->work, xfrm_policy_worker); INIT_LIST_HEAD(&policy->bytype); INIT_HLIST_NODE(&policy->bydst); INIT_HLIST_NODE(&policy->byidx); rwlock_init(&policy->lock); atomic_set(&policy->refcnt, 1); - setup_timer(&policy->timer, xfrm_policy_timer, - (unsigned long)policy); } return policy; } @@ -256,7 +256,7 @@ void xfrm_policy_destroy(struct xfrm_policy *policy) BUG_ON(policy->bundles); - if (del_timer(&policy->timer)) + if (cancel_delayed_work(&policy->work)) BUG(); write_lock_bh(&xfrm_policy_lock); @@ -277,7 +277,7 @@ static void xfrm_policy_gc_kill(struct xfrm_policy *policy) dst_free(dst); } - if (del_timer(&policy->timer)) + if (cancel_delayed_work(&policy->work)) atomic_dec(&policy->refcnt); if (atomic_read(&policy->refcnt) > 1) @@ -615,7 +615,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) hlist_add_head(&policy->byidx, xfrm_policy_byidx+idx_hash(policy->index)); policy->curlft.add_time = get_seconds(); policy->curlft.use_time = 0; - if (!mod_timer(&policy->timer, jiffies + HZ)) + if (!schedule_delayed_work(&policy->work, HZ)) xfrm_pol_hold(policy); list_add_tail(&policy->bytype, &xfrm_policy_bytype[policy->type]); write_unlock_bh(&xfrm_policy_lock); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 72fddaf..b384d81 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -380,8 +380,8 @@ static void xfrm_put_mode(struct xfrm_mode *mode) static void xfrm_state_gc_destroy(struct xfrm_state *x) { - del_timer_sync(&x->timer); - del_timer_sync(&x->rtimer); + cancel_delayed_work_sync(&x->work); + cancel_delayed_work_sync(&x->rwork); kfree(x->aalg); kfree(x->ealg); kfree(x->calg); @@ -426,15 +426,16 @@ static inline unsigned long make_jiffies(long secs) return secs*HZ; } -static void xfrm_timer_handler(unsigned long data) +static void xfrm_work_handler(struct work_struct *w) { - struct xfrm_state *x = (struct xfrm_state*)data; + struct xfrm_state *x = + container_of((struct delayed_work *)w, struct xfrm_state, work); unsigned long now = get_seconds(); long next = LONG_MAX; int warn = 0; int err = 0; - spin_lock(&x->lock); + spin_lock_bh(&x->lock); if (x->km.state == XFRM_STATE_DEAD) goto out; if (x->km.state == XFRM_STATE_EXPIRED) @@ -479,7 +480,7 @@ static void xfrm_timer_handler(unsigned long data) km_state_expired(x, 0, 0); resched: if (next != LONG_MAX) - mod_timer(&x->timer, jiffies + make_jiffies(next)); + schedule_delayed_work(&x->work, make_jiffies(next)); goto out; @@ -500,10 +501,10 @@ expired: audit_get_sessionid(current), 0); out: - spin_unlock(&x->lock); + spin_unlock_bh(&x->lock); } -static void xfrm_replay_timer_handler(unsigned long data); +static void xfrm_replay_work_handler(struct work_struct *); struct xfrm_state *xfrm_state_alloc(void) { @@ -518,9 +519,8 @@ struct xfrm_state *xfrm_state_alloc(void) INIT_HLIST_NODE(&x->bydst); INIT_HLIST_NODE(&x->bysrc); INIT_HLIST_NODE(&x->byspi); - setup_timer(&x->timer, xfrm_timer_handler, (unsigned long)x); - setup_timer(&x->rtimer, xfrm_replay_timer_handler, - (unsigned long)x); + INIT_DELAYED_WORK(&x->work, xfrm_work_handler); + INIT_DELAYED_WORK(&x->rwork, xfrm_replay_work_handler); x->curlft.add_time = get_seconds(); x->lft.soft_byte_limit = XFRM_INF; x->lft.soft_packet_limit = XFRM_INF; @@ -864,8 +864,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, hlist_add_head(&x->byspi, xfrm_state_byspi+h); } x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires; - x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; - add_timer(&x->timer); + schedule_delayed_work(&x->work, sysctl_xfrm_acq_expires*HZ); xfrm_state_num++; xfrm_hash_grow_check(x->bydst.next != NULL); } else { @@ -938,9 +937,9 @@ static void __xfrm_state_insert(struct xfrm_state *x) hlist_add_head(&x->byspi, xfrm_state_byspi+h); } - mod_timer(&x->timer, jiffies + HZ); + schedule_delayed_work(&x->work, HZ); if (x->replay_maxage) - mod_timer(&x->rtimer, jiffies + x->replay_maxage); + schedule_delayed_work(&x->rwork, x->replay_maxage); wake_up(&km_waitq); @@ -1049,8 +1048,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re x->props.reqid = reqid; x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires; xfrm_state_hold(x); - x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; - add_timer(&x->timer); + schedule_delayed_work(&x->work, sysctl_xfrm_acq_expires*HZ); hlist_add_head(&x->bydst, xfrm_state_bydst+h); h = xfrm_src_hash(daddr, saddr, family); hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); @@ -1317,7 +1315,7 @@ out: memcpy(&x1->lft, &x->lft, sizeof(x1->lft)); x1->km.dying = 0; - mod_timer(&x1->timer, jiffies + HZ); + schedule_delayed_work(&x1->work, HZ); if (x1->curlft.use_time) xfrm_state_check_expire(x1); @@ -1342,7 +1340,7 @@ int xfrm_state_check_expire(struct xfrm_state *x) if (x->curlft.bytes >= x->lft.hard_byte_limit || x->curlft.packets >= x->lft.hard_packet_limit) { x->km.state = XFRM_STATE_EXPIRED; - mod_timer(&x->timer, jiffies); + schedule_delayed_work(&x->work, 0); return -EINVAL; } @@ -1622,15 +1620,16 @@ void xfrm_replay_notify(struct xfrm_state *x, int event) km_state_notify(x, &c); if (x->replay_maxage && - !mod_timer(&x->rtimer, jiffies + x->replay_maxage)) + !schedule_delayed_work(&x->rwork, x->replay_maxage)) x->xflags &= ~XFRM_TIME_DEFER; } -static void xfrm_replay_timer_handler(unsigned long data) +static void xfrm_replay_work_handler(struct work_struct *w) { - struct xfrm_state *x = (struct xfrm_state*)data; + struct xfrm_state *x = + container_of((struct delayed_work *)w, struct xfrm_state, rwork); - spin_lock(&x->lock); + spin_lock_bh(&x->lock); if (x->km.state == XFRM_STATE_VALID) { if (xfrm_aevent_is_on()) @@ -1639,7 +1638,7 @@ static void xfrm_replay_timer_handler(unsigned long data) x->xflags |= XFRM_TIME_DEFER; } - spin_unlock(&x->lock); + spin_unlock_bh(&x->lock); } int xfrm_replay_check(struct xfrm_state *x, ^ permalink raw reply related [flat|nested] 17+ messages in thread
end of thread, other threads:[~2008-05-06 3:53 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-02-16 15:55 [Patch]net/xfrm/xfrm_policy.c: replace timer with delayed_work WANG Cong 2008-04-27 1:18 ` Herbert Xu 2008-04-28 14:53 ` WANG Cong 2008-04-28 15:13 ` Herbert Xu 2008-04-30 16:06 ` WANG Cong 2008-05-01 1:11 ` Herbert Xu 2008-05-02 5:21 ` WANG Cong 2008-05-02 5:35 ` [Patch] (revised) net/xfrm/xfrm_policy.c: " WANG Cong 2008-05-02 23:54 ` David Miller 2008-05-03 14:46 ` WANG Cong 2008-05-03 15:06 ` Herbert Xu 2008-05-03 15:31 ` WANG Cong 2008-05-04 1:38 ` David Miller 2008-05-04 1:37 ` David Miller 2008-05-06 3:08 ` Herbert Xu 2008-05-06 3:57 ` WANG Cong 2008-05-02 5:43 ` [Patch](Revised) net/xfrm/xfrm_state.c: " WANG Cong
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).