aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/protocol.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r--net/sctp/protocol.c46
1 files changed, 38 insertions, 8 deletions
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index ab0d538a74ed..1099e99a53c4 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -60,6 +60,8 @@
60#include <net/inet_common.h> 60#include <net/inet_common.h>
61#include <net/inet_ecn.h> 61#include <net/inet_ecn.h>
62 62
63#define MAX_SCTP_PORT_HASH_ENTRIES (64 * 1024)
64
63/* Global data structures. */ 65/* Global data structures. */
64struct sctp_globals sctp_globals __read_mostly; 66struct sctp_globals sctp_globals __read_mostly;
65 67
@@ -1355,6 +1357,8 @@ static __init int sctp_init(void)
1355 unsigned long limit; 1357 unsigned long limit;
1356 int max_share; 1358 int max_share;
1357 int order; 1359 int order;
1360 int num_entries;
1361 int max_entry_order;
1358 1362
1359 sock_skb_cb_check_size(sizeof(struct sctp_ulpevent)); 1363 sock_skb_cb_check_size(sizeof(struct sctp_ulpevent));
1360 1364
@@ -1407,14 +1411,24 @@ static __init int sctp_init(void)
1407 1411
1408 /* Size and allocate the association hash table. 1412 /* Size and allocate the association hash table.
1409 * The methodology is similar to that of the tcp hash tables. 1413 * The methodology is similar to that of the tcp hash tables.
1414 * Though not identical. Start by getting a goal size
1410 */ 1415 */
1411 if (totalram_pages >= (128 * 1024)) 1416 if (totalram_pages >= (128 * 1024))
1412 goal = totalram_pages >> (22 - PAGE_SHIFT); 1417 goal = totalram_pages >> (22 - PAGE_SHIFT);
1413 else 1418 else
1414 goal = totalram_pages >> (24 - PAGE_SHIFT); 1419 goal = totalram_pages >> (24 - PAGE_SHIFT);
1415 1420
1416 for (order = 0; (1UL << order) < goal; order++) 1421 /* Then compute the page order for said goal */
1417 ; 1422 order = get_order(goal);
1423
1424 /* Now compute the required page order for the maximum sized table we
1425 * want to create
1426 */
1427 max_entry_order = get_order(MAX_SCTP_PORT_HASH_ENTRIES *
1428 sizeof(struct sctp_bind_hashbucket));
1429
1430 /* Limit the page order by that maximum hash table size */
1431 order = min(order, max_entry_order);
1418 1432
1419 /* Allocate and initialize the endpoint hash table. */ 1433 /* Allocate and initialize the endpoint hash table. */
1420 sctp_ep_hashsize = 64; 1434 sctp_ep_hashsize = 64;
@@ -1430,20 +1444,35 @@ static __init int sctp_init(void)
1430 INIT_HLIST_HEAD(&sctp_ep_hashtable[i].chain); 1444 INIT_HLIST_HEAD(&sctp_ep_hashtable[i].chain);
1431 } 1445 }
1432 1446
1433 /* Allocate and initialize the SCTP port hash table. */ 1447 /* Allocate and initialize the SCTP port hash table.
1448 * Note that order is initalized to start at the max sized
1449 * table we want to support. If we can't get that many pages
1450 * reduce the order and try again
1451 */
1434 do { 1452 do {
1435 sctp_port_hashsize = (1UL << order) * PAGE_SIZE /
1436 sizeof(struct sctp_bind_hashbucket);
1437 if ((sctp_port_hashsize > (64 * 1024)) && order > 0)
1438 continue;
1439 sctp_port_hashtable = (struct sctp_bind_hashbucket *) 1453 sctp_port_hashtable = (struct sctp_bind_hashbucket *)
1440 __get_free_pages(GFP_KERNEL | __GFP_NOWARN, order); 1454 __get_free_pages(GFP_KERNEL | __GFP_NOWARN, order);
1441 } while (!sctp_port_hashtable && --order > 0); 1455 } while (!sctp_port_hashtable && --order > 0);
1456
1442 if (!sctp_port_hashtable) { 1457 if (!sctp_port_hashtable) {
1443 pr_err("Failed bind hash alloc\n"); 1458 pr_err("Failed bind hash alloc\n");
1444 status = -ENOMEM; 1459 status = -ENOMEM;
1445 goto err_bhash_alloc; 1460 goto err_bhash_alloc;
1446 } 1461 }
1462
1463 /* Now compute the number of entries that will fit in the
1464 * port hash space we allocated
1465 */
1466 num_entries = (1UL << order) * PAGE_SIZE /
1467 sizeof(struct sctp_bind_hashbucket);
1468
1469 /* And finish by rounding it down to the nearest power of two
1470 * this wastes some memory of course, but its needed because
1471 * the hash function operates based on the assumption that
1472 * that the number of entries is a power of two
1473 */
1474 sctp_port_hashsize = rounddown_pow_of_two(num_entries);
1475
1447 for (i = 0; i < sctp_port_hashsize; i++) { 1476 for (i = 0; i < sctp_port_hashsize; i++) {
1448 spin_lock_init(&sctp_port_hashtable[i].lock); 1477 spin_lock_init(&sctp_port_hashtable[i].lock);
1449 INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain); 1478 INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain);
@@ -1452,7 +1481,8 @@ static __init int sctp_init(void)
1452 if (sctp_transport_hashtable_init()) 1481 if (sctp_transport_hashtable_init())
1453 goto err_thash_alloc; 1482 goto err_thash_alloc;
1454 1483
1455 pr_info("Hash tables configured (bind %d)\n", sctp_port_hashsize); 1484 pr_info("Hash tables configured (bind %d/%d)\n", sctp_port_hashsize,
1485 num_entries);
1456 1486
1457 sctp_sysctl_register(); 1487 sctp_sysctl_register();
1458 1488