aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/flow.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/flow.c')
-rw-r--r--net/core/flow.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/net/core/flow.c b/net/core/flow.c
index 96015871ecea..f032d1c37192 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -39,9 +39,10 @@ atomic_t flow_cache_genid = ATOMIC_INIT(0);
39 39
40static u32 flow_hash_shift; 40static u32 flow_hash_shift;
41#define flow_hash_size (1 << flow_hash_shift) 41#define flow_hash_size (1 << flow_hash_shift)
42static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
43 42
44#define flow_table(cpu) (per_cpu(flow_tables, cpu)) 43static DEFINE_PER_CPU_LOCKED(struct flow_cache_entry **, flow_tables);
44
45#define flow_table(cpu) (per_cpu_var_locked(flow_tables, cpu))
45 46
46static struct kmem_cache *flow_cachep __read_mostly; 47static struct kmem_cache *flow_cachep __read_mostly;
47 48
@@ -168,24 +169,24 @@ static int flow_key_compare(struct flowi *key1, struct flowi *key2)
168void *flow_cache_lookup(struct net *net, struct flowi *key, u16 family, u8 dir, 169void *flow_cache_lookup(struct net *net, struct flowi *key, u16 family, u8 dir,
169 flow_resolve_t resolver) 170 flow_resolve_t resolver)
170{ 171{
171 struct flow_cache_entry *fle, **head; 172 struct flow_cache_entry **table, *fle, **head;
172 unsigned int hash; 173 unsigned int hash;
173 int cpu; 174 int cpu;
174 175
175 local_bh_disable(); 176 local_bh_disable();
176 cpu = smp_processor_id(); 177 table = get_cpu_var_locked(flow_tables, &cpu);
177 178
178 fle = NULL; 179 fle = NULL;
179 /* Packet really early in init? Making flow_cache_init a 180 /* Packet really early in init? Making flow_cache_init a
180 * pre-smp initcall would solve this. --RR */ 181 * pre-smp initcall would solve this. --RR */
181 if (!flow_table(cpu)) 182 if (!table)
182 goto nocache; 183 goto nocache;
183 184
184 if (flow_hash_rnd_recalc(cpu)) 185 if (flow_hash_rnd_recalc(cpu))
185 flow_new_hash_rnd(cpu); 186 flow_new_hash_rnd(cpu);
186 hash = flow_hash_code(key, cpu); 187 hash = flow_hash_code(key, cpu);
187 188
188 head = &flow_table(cpu)[hash]; 189 head = &table[hash];
189 for (fle = *head; fle; fle = fle->next) { 190 for (fle = *head; fle; fle = fle->next) {
190 if (fle->family == family && 191 if (fle->family == family &&
191 fle->dir == dir && 192 fle->dir == dir &&
@@ -195,6 +196,7 @@ void *flow_cache_lookup(struct net *net, struct flowi *key, u16 family, u8 dir,
195 196
196 if (ret) 197 if (ret)
197 atomic_inc(fle->object_ref); 198 atomic_inc(fle->object_ref);
199 put_cpu_var_locked(flow_tables, cpu);
198 local_bh_enable(); 200 local_bh_enable();
199 201
200 return ret; 202 return ret;
@@ -220,6 +222,8 @@ void *flow_cache_lookup(struct net *net, struct flowi *key, u16 family, u8 dir,
220 } 222 }
221 223
222nocache: 224nocache:
225 put_cpu_var_locked(flow_tables, cpu);
226
223 { 227 {
224 int err; 228 int err;
225 void *obj; 229 void *obj;
@@ -249,14 +253,15 @@ nocache:
249static void flow_cache_flush_tasklet(unsigned long data) 253static void flow_cache_flush_tasklet(unsigned long data)
250{ 254{
251 struct flow_flush_info *info = (void *)data; 255 struct flow_flush_info *info = (void *)data;
256 struct flow_cache_entry **table;
252 int i; 257 int i;
253 int cpu; 258 int cpu;
254 259
255 cpu = smp_processor_id(); 260 table = get_cpu_var_locked(flow_tables, &cpu);
256 for (i = 0; i < flow_hash_size; i++) { 261 for (i = 0; i < flow_hash_size; i++) {
257 struct flow_cache_entry *fle; 262 struct flow_cache_entry *fle;
258 263
259 fle = flow_table(cpu)[i]; 264 fle = table[i];
260 for (; fle; fle = fle->next) { 265 for (; fle; fle = fle->next) {
261 unsigned genid = atomic_read(&flow_cache_genid); 266 unsigned genid = atomic_read(&flow_cache_genid);
262 267
@@ -267,6 +272,7 @@ static void flow_cache_flush_tasklet(unsigned long data)
267 atomic_dec(fle->object_ref); 272 atomic_dec(fle->object_ref);
268 } 273 }
269 } 274 }
275 put_cpu_var_locked(flow_tables, cpu);
270 276
271 if (atomic_dec_and_test(&info->cpuleft)) 277 if (atomic_dec_and_test(&info->cpuleft))
272 complete(&info->completion); 278 complete(&info->completion);