From: Julian Anastasov An addition to the last ipvs changes that move update_defense_level/si_meminfo to keventd: - ip_vs_random_dropentry now runs in process context and should use _bh locks to protect from softirqs - update_defense_level still needs _bh locks after si_meminfo is called, for the same purpose Signed-off-by: Julian Anastasov Cc: "David S. Miller" Signed-off-by: Andrew Morton --- net/ipv4/ipvs/ip_vs_conn.c | 6 +++--- net/ipv4/ipvs/ip_vs_ctl.c | 9 ++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff -puN net/ipv4/ipvs/ip_vs_conn.c~ipvs-add-and-reorder-bh-locks-after-moving-to-keventd net/ipv4/ipvs/ip_vs_conn.c --- devel/net/ipv4/ipvs/ip_vs_conn.c~ipvs-add-and-reorder-bh-locks-after-moving-to-keventd 2005-07-08 23:11:20.000000000 -0700 +++ devel-akpm/net/ipv4/ipvs/ip_vs_conn.c 2005-07-08 23:11:20.000000000 -0700 @@ -758,7 +758,7 @@ static inline int todrop_entry(struct ip return 1; } - +/* Called from keventd and must protect itself from softirqs */ void ip_vs_random_dropentry(void) { int idx; @@ -773,7 +773,7 @@ void ip_vs_random_dropentry(void) /* * Lock is actually needed in this loop. */ - ct_write_lock(hash); + ct_write_lock_bh(hash); list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { if (!cp->cport && !(cp->flags & IP_VS_CONN_F_NO_CPORT)) @@ -806,7 +806,7 @@ void ip_vs_random_dropentry(void) ip_vs_conn_expire_now(cp->control); } } - ct_write_unlock(hash); + ct_write_unlock_bh(hash); } } diff -puN net/ipv4/ipvs/ip_vs_ctl.c~ipvs-add-and-reorder-bh-locks-after-moving-to-keventd net/ipv4/ipvs/ip_vs_ctl.c --- devel/net/ipv4/ipvs/ip_vs_ctl.c~ipvs-add-and-reorder-bh-locks-after-moving-to-keventd 2005-07-08 23:11:20.000000000 -0700 +++ devel-akpm/net/ipv4/ipvs/ip_vs_ctl.c 2005-07-08 23:11:20.000000000 -0700 @@ -90,7 +90,8 @@ int ip_vs_get_debug_level(void) #endif /* - * update_defense_level is called from keventd and from sysctl. + * update_defense_level is called from keventd and from sysctl, + * so it needs to protect itself from softirqs */ static void update_defense_level(void) { @@ -110,6 +111,8 @@ static void update_defense_level(void) nomem = (availmem < sysctl_ip_vs_amemthresh); + local_bh_disable(); + /* drop_entry */ spin_lock(&__ip_vs_dropentry_lock); switch (sysctl_ip_vs_drop_entry) { @@ -206,6 +209,8 @@ static void update_defense_level(void) if (to_change >= 0) ip_vs_protocol_timeout_change(sysctl_ip_vs_secure_tcp>1); write_unlock(&__ip_vs_securetcp_lock); + + local_bh_enable(); } @@ -1360,9 +1365,7 @@ proc_do_defense_mode(ctl_table *table, i /* Restore the correct value */ *valp = val; } else { - local_bh_disable(); update_defense_level(); - local_bh_enable(); } } return rc; _