aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/udp.c
diff options
context:
space:
mode:
authorTim Bird <tim.bird@am.sony.com>2012-05-23 09:33:35 -0400
committerDavid S. Miller <davem@davemloft.net>2012-05-24 00:28:21 -0400
commit31fe62b9586643953f0c0c37a6357dafc69034e2 (patch)
tree69f9990423969df4ecbaea9d1e8de748284bea5e /net/ipv4/udp.c
parentd0a24a3516fb36023bef28d2355fa34e7f32029f (diff)
mm: add a low limit to alloc_large_system_hash
UDP stack needs a minimum hash size value for proper operation and also uses alloc_large_system_hash() for proper NUMA distribution of its hash tables and automatic sizing depending on available system memory. On some low memory situations, udp_table_init() must ignore the alloc_large_system_hash() result and reallocs a bigger memory area. As we cannot easily free old hash table, we leak it and kmemleak can issue a warning. This patch adds a low limit parameter to alloc_large_system_hash() to solve this problem. We then specify UDP_HTABLE_SIZE_MIN for UDP/UDPLite hash table allocation. Reported-by: Mark Asselstine <mark.asselstine@windriver.com> Reported-by: Tim Bird <tim.bird@am.sony.com> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r--net/ipv4/udp.c30
1 files changed, 10 insertions, 20 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 609397ee78fb..eaca73644e79 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2192,26 +2192,16 @@ void __init udp_table_init(struct udp_table *table, const char *name)
2192{ 2192{
2193 unsigned int i; 2193 unsigned int i;
2194 2194
2195 if (!CONFIG_BASE_SMALL) 2195 table->hash = alloc_large_system_hash(name,
2196 table->hash = alloc_large_system_hash(name, 2196 2 * sizeof(struct udp_hslot),
2197 2 * sizeof(struct udp_hslot), 2197 uhash_entries,
2198 uhash_entries, 2198 21, /* one slot per 2 MB */
2199 21, /* one slot per 2 MB */ 2199 0,
2200 0, 2200 &table->log,
2201 &table->log, 2201 &table->mask,
2202 &table->mask, 2202 UDP_HTABLE_SIZE_MIN,
2203 64 * 1024); 2203 64 * 1024);
2204 /* 2204
2205 * Make sure hash table has the minimum size
2206 */
2207 if (CONFIG_BASE_SMALL || table->mask < UDP_HTABLE_SIZE_MIN - 1) {
2208 table->hash = kmalloc(UDP_HTABLE_SIZE_MIN *
2209 2 * sizeof(struct udp_hslot), GFP_KERNEL);
2210 if (!table->hash)
2211 panic(name);
2212 table->log = ilog2(UDP_HTABLE_SIZE_MIN);
2213 table->mask = UDP_HTABLE_SIZE_MIN - 1;
2214 }
2215 table->hash2 = table->hash + (table->mask + 1); 2205 table->hash2 = table->hash + (table->mask + 1);
2216 for (i = 0; i <= table->mask; i++) { 2206 for (i = 0; i <= table->mask; i++) {
2217 INIT_HLIST_NULLS_HEAD(&table->hash[i].head, i); 2207 INIT_HLIST_NULLS_HEAD(&table->hash[i].head, i);