Commit 0ee27163 authored by David S. Miller's avatar David S. Miller

[NET]: Regenerate flow cache hash rnd more sanely.

parent 4e98121d
...@@ -34,13 +34,15 @@ static kmem_cache_t *flow_cachep; ...@@ -34,13 +34,15 @@ static kmem_cache_t *flow_cachep;
static int flow_lwm, flow_hwm; static int flow_lwm, flow_hwm;
struct flow_percpu_info { struct flow_percpu_info {
int hash_rnd_recalc;
u32 hash_rnd; u32 hash_rnd;
int number; int count;
} ____cacheline_aligned; } ____cacheline_aligned;
static struct flow_percpu_info flow_hash_info[NR_CPUS]; static struct flow_percpu_info flow_hash_info[NR_CPUS];
#define flow_count(cpu) (flow_hash_info[cpu].number) #define flow_hash_rnd_recalc(cpu) (flow_hash_info[cpu].hash_rnd_recalc)
#define flow_hash_rnd(cpu) (flow_hash_info[cpu].hash_rnd) #define flow_hash_rnd(cpu) (flow_hash_info[cpu].hash_rnd)
#define flow_count(cpu) (flow_hash_info[cpu].count)
static struct timer_list flow_hash_rnd_timer; static struct timer_list flow_hash_rnd_timer;
...@@ -51,16 +53,15 @@ static void flow_cache_new_hashrnd(unsigned long arg) ...@@ -51,16 +53,15 @@ static void flow_cache_new_hashrnd(unsigned long arg)
int i; int i;
for (i = 0; i < NR_CPUS; i++) for (i = 0; i < NR_CPUS; i++)
get_random_bytes(&flow_hash_rnd(i), sizeof(u32)); flow_hash_rnd_recalc(i) = 1;
flow_hash_rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD; flow_hash_rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD;
add_timer(&flow_hash_rnd_timer); add_timer(&flow_hash_rnd_timer);
} }
static void flow_cache_shrink(int cpu) static void __flow_cache_shrink(int cpu, int shrink_to)
{ {
struct flow_cache_entry *fle, **flp; struct flow_cache_entry *fle, **flp;
int shrink_to = flow_lwm / flow_hash_size;
int i; int i;
for (i = 0; i < flow_hash_size; i++) { for (i = 0; i < flow_hash_size; i++) {
...@@ -81,6 +82,21 @@ static void flow_cache_shrink(int cpu) ...@@ -81,6 +82,21 @@ static void flow_cache_shrink(int cpu)
} }
} }
static void flow_cache_shrink(int cpu)
{
int shrink_to = flow_lwm / flow_hash_size;
__flow_cache_shrink(cpu, shrink_to);
}
static void flow_new_hash_rnd(int cpu)
{
get_random_bytes(&flow_hash_rnd(cpu), sizeof(u32));
flow_hash_rnd_recalc(cpu) = 0;
__flow_cache_shrink(cpu, 0);
}
static u32 flow_hash_code(struct flowi *key, int cpu) static u32 flow_hash_code(struct flowi *key, int cpu)
{ {
u32 *k = (u32 *) key; u32 *k = (u32 *) key;
...@@ -131,6 +147,8 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, ...@@ -131,6 +147,8 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
local_bh_disable(); local_bh_disable();
cpu = smp_processor_id(); cpu = smp_processor_id();
if (flow_hash_rnd_recalc(cpu))
flow_new_hash_rnd(cpu);
hash = flow_hash_code(key, cpu); hash = flow_hash_code(key, cpu);
head = &flow_table[(cpu << flow_hash_shift) + hash]; head = &flow_table[(cpu << flow_hash_shift) + hash];
...@@ -208,12 +226,8 @@ static int __init flow_cache_init(void) ...@@ -208,12 +226,8 @@ static int __init flow_cache_init(void)
flow_lwm = 2 * flow_hash_size; flow_lwm = 2 * flow_hash_size;
flow_hwm = 4 * flow_hash_size; flow_hwm = 4 * flow_hash_size;
for (i = 0; i < NR_CPUS; i++) { for (i = 0; i < NR_CPUS; i++)
flow_hash_rnd(i) = flow_hash_rnd_recalc(i) = 1;
(u32) ((num_physpages ^ (num_physpages>>8)) ^
(jiffies ^ (jiffies >> 7)));
flow_hash_rnd(i) ^= i;
}
init_timer(&flow_hash_rnd_timer); init_timer(&flow_hash_rnd_timer);
flow_hash_rnd_timer.function = flow_cache_new_hashrnd; flow_hash_rnd_timer.function = flow_cache_new_hashrnd;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment