1) release refcnt of old dests in lookup entry
2) handle exception about svc->num_dests == 0
- skip permutate and populate if dest list is empty
3) change allocation method
- in case of allocating permutate array, use vmalloc()
instead of kalloc()
Signed-off-by: Inju Song <inju.song@xxxxxxxxxxxxx>
---
net/netfilter/ipvs/ip_vs_mh.c | 58 +++++++++++++++++++++++++++++--------------
1 file changed, 39 insertions(+), 19 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_mh.c b/net/netfilter/ipvs/ip_vs_mh.c
index b3fa8c4..bb20b96 100644
--- a/net/netfilter/ipvs/ip_vs_mh.c
+++ b/net/netfilter/ipvs/ip_vs_mh.c
@@ -5,6 +5,7 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/vmalloc.h>
#include <linux/skbuff.h>
#include <net/ip_vs.h>
@@ -74,6 +75,12 @@ static inline int ip_vs_mh_permutate(struct ip_vs_mh_state
*s,
struct list_head *p;
struct ip_vs_dest *dest;
unsigned int offset, skip;
+ bool empty;
+
+ p = &svc->destinations;
+ empty = list_empty(p);
+ if (empty)
+ return 0;
/* extending permutation table to 2d arrays */
for (i = 1; i < svc->num_dests; i++)
@@ -81,7 +88,6 @@ static inline int ip_vs_mh_permutate(struct ip_vs_mh_state *s,
IP_VS_MH_LOOKUP_SIZE;
i = 0;
- p = &svc->destinations;
while ((p = p->next) != &svc->destinations) {
dest = list_entry(p, struct ip_vs_dest, n_list);
offset = ip_vs_mh_hashkey(svc->af, &dest->addr, dest->port,
@@ -110,6 +116,7 @@ static inline int ip_vs_mh_permutate(struct ip_vs_mh_state
*s,
struct list_head *p;
struct ip_vs_dest *dest;
unsigned int n, c;
+ bool empty;
ret = 0;
next = kcalloc(IP_VS_MH_TAB_SIZE, sizeof(unsigned int),
@@ -128,11 +135,17 @@ static inline int ip_vs_mh_permutate(struct
ip_vs_mh_state *s,
RCU_INIT_POINTER(entry[i].dest, NULL);
n = 0;
+ p = &svc->destinations;
+ empty = list_empty(p);
+ if (empty)
+ goto out;
+
pmt = s->permutation;
while (n < IP_VS_MH_LOOKUP_SIZE) {
- p = &svc->destinations;
for (i = 0; i < svc->num_dests; i++) {
- p = p->next;
+ if (p == &svc->destinations)
+ p = p->next;
+
c = pmt[i][next[i]];
while (entry[c].dest) {
@@ -147,20 +160,29 @@ static inline int ip_vs_mh_permutate(struct
ip_vs_mh_state *s,
n++;
if (n == IP_VS_MH_LOOKUP_SIZE)
break;
+
+ p = p->next;
}
}
+out:
l = &s->lookup[0];
for (i = 0; i < IP_VS_MH_LOOKUP_SIZE; i++) {
dest = rcu_dereference_protected(entry[i].dest, 1);
- ip_vs_dest_hold(dest);
- RCU_INIT_POINTER(l->dest, dest);
+ if (dest)
+ ip_vs_dest_put(dest);
+ if (empty) {
+ RCU_INIT_POINTER(l->dest, NULL);
+ } else {
+ ip_vs_dest_hold(dest);
+ RCU_INIT_POINTER(l->dest, dest);
- IP_VS_DBG_BUF(6, "assigned i: %d dest: %s weight: %d\n",
- i, IP_VS_DBG_ADDR(dest->af, &dest->addr),
- atomic_read(&dest->weight));
+ IP_VS_DBG_BUF(6, "assigned i: %d dest: %s weight: %d\n",
+ i, IP_VS_DBG_ADDR(dest->af, &dest->addr),
+ atomic_read(&dest->weight));
- RCU_INIT_POINTER(entry[i].dest, NULL);
+ RCU_INIT_POINTER(entry[i].dest, NULL);
+ }
l++;
}
@@ -250,19 +272,15 @@ static void ip_vs_mh_flush(struct ip_vs_mh_state *s)
{
int ret;
- /* flush all the hash entry before assigning mh entry */
- ip_vs_mh_flush(s);
-
/* ip_vs_mh_reassign is responsible for assigning
* and releasing s->permutation table
*/
- s->permutation = kcalloc(IP_VS_MH_TAB_SIZE, sizeof(unsigned int *),
- GFP_KERNEL);
+ s->permutation = vzalloc(IP_VS_MH_TAB_SIZE * sizeof(unsigned int *));
if (!s->permutation)
return -ENOMEM;
- s->permutation[0] = kcalloc(IP_VS_MH_TAB_SIZE * IP_VS_MH_LOOKUP_SIZE,
- sizeof(unsigned int), GFP_KERNEL);
+ s->permutation[0] = vzalloc(IP_VS_MH_TAB_SIZE * IP_VS_MH_LOOKUP_SIZE *
+ sizeof(unsigned int));
if (!s->permutation[0]) {
ret = -ENOMEM;
goto err_alloc;
@@ -276,12 +294,14 @@ static void ip_vs_mh_flush(struct ip_vs_mh_state *s)
if (ret < 0)
goto err_out;
- return 0;
+ IP_VS_DBG_BUF(6, "MH: reassign lookup table of %s:%d\n",
+ IP_VS_DBG_ADDR(svc->af, &svc->addr),
+ ntohs(svc->port));
err_out:
- kfree(s->permutation[0]);
+ vfree(s->permutation[0]);
err_alloc:
- kfree(s->permutation);
+ vfree(s->permutation);
return ret;
}
--
1.8.3.1
--
Inju Song
NAVER Corporation
--
To unsubscribe from this list: send the line "unsubscribe lvs-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
|