On Thu, Jun 12, 2003 at 03:18:45AM -0700, David S. Miller wrote: > > Ok, I guess we have to stick with a smp_call_function() based scheme. In that case, I'll send the rest of that patch after the splitting. You should've got the one about the preempt race. This one removes the object argument from flow_cache_flush and makes it flush all out-of-date entries. -- Debian GNU/Linux 3.0 is out! ( http://www.debian.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
--- kernel-source-2.5/net/core/flow.c.orig 2003-06-12 20:24:53.000000000 +1000 +++ kernel-source-2.5/net/core/flow.c 2003-06-12 20:27:43.000000000 +1000 @@ -54,7 +54,6 @@ #define FLOW_HASH_RND_PERIOD (10 * 60 * HZ) struct flow_flush_info { - void *object; atomic_t cpuleft; struct completion completion; }; @@ -224,18 +223,20 @@ static void flow_cache_flush_tasklet(unsigned long data) { struct flow_flush_info *info = (void *)data; - void *object = info->object; int i; int cpu; cpu = smp_processor_id(); for (i = 0; i < flow_hash_size; i++) { - struct flow_cache_entry *fle, **flp; + struct flow_cache_entry *fle; - flp = &flow_table[(cpu << flow_hash_shift) + i]; - for (; (fle = *flp) != NULL; flp = &fle->next) { - if (fle->object != object) + fle = flow_table[(cpu << flow_hash_shift) + i]; + for (; fle; fle = fle->next) { + unsigned genid = atomic_read(&flow_cache_genid); + + if (!fle->object || fle->genid == genid) continue; + fle->object = NULL; atomic_dec(fle->object_ref); } @@ -257,11 +258,10 @@ tasklet_schedule(tasklet); } -void flow_cache_flush(void *object) +void flow_cache_flush(void) { struct flow_flush_info info; - info.object = object; atomic_set(&info.cpuleft, num_online_cpus()); init_completion(&info.completion); Index: kernel-source-2.5/include/net/flow.h =================================================================== RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/include/net/flow.h,v retrieving revision 1.2 diff -u -r1.2 flow.h --- kernel-source-2.5/include/net/flow.h 10 Jun 2003 09:19:10 -0000 1.2 +++ kernel-source-2.5/include/net/flow.h 11 Jun 2003 08:32:39 -0000 @@ -87,7 +87,7 @@ extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, flow_resolve_t resolver); -extern void flow_cache_flush(void *object); +extern void flow_cache_flush(void); extern atomic_t flow_cache_genid; #endif Index: kernel-source-2.5/net/xfrm/xfrm_policy.c =================================================================== RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/xfrm/xfrm_policy.c,v retrieving revision 1.6 diff -u -r1.6 xfrm_policy.c --- kernel-source-2.5/net/xfrm/xfrm_policy.c 10 Jun 2003 09:19:24 -0000 1.6 +++ kernel-source-2.5/net/xfrm/xfrm_policy.c 11 Jun 2003 08:32:47 -0000 @@ -214,7 +214,7 @@ atomic_dec(&policy->refcnt); if (atomic_read(&policy->refcnt) > 1) - flow_cache_flush(policy); + flow_cache_flush(); xfrm_pol_put(policy); }