aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/sock.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/sock.c')
-rw-r--r--net/core/sock.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/net/core/sock.c b/net/core/sock.c
index a1a23be10aa3..aba31fedf2ac 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1378,7 +1378,8 @@ static LIST_HEAD(proto_list);
1378 1378
1379int proto_register(struct proto *prot, int alloc_slab) 1379int proto_register(struct proto *prot, int alloc_slab)
1380{ 1380{
1381 char *request_sock_slab_name; 1381 char *request_sock_slab_name = NULL;
1382 char *timewait_sock_slab_name;
1382 int rc = -ENOBUFS; 1383 int rc = -ENOBUFS;
1383 1384
1384 if (alloc_slab) { 1385 if (alloc_slab) {
@@ -1409,6 +1410,23 @@ int proto_register(struct proto *prot, int alloc_slab)
1409 goto out_free_request_sock_slab_name; 1410 goto out_free_request_sock_slab_name;
1410 } 1411 }
1411 } 1412 }
1413
1414 if (prot->twsk_obj_size) {
1415 static const char mask[] = "tw_sock_%s";
1416
1417 timewait_sock_slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL);
1418
1419 if (timewait_sock_slab_name == NULL)
1420 goto out_free_request_sock_slab;
1421
1422 sprintf(timewait_sock_slab_name, mask, prot->name);
1423 prot->twsk_slab = kmem_cache_create(timewait_sock_slab_name,
1424 prot->twsk_obj_size,
1425 0, SLAB_HWCACHE_ALIGN,
1426 NULL, NULL);
1427 if (prot->twsk_slab == NULL)
1428 goto out_free_timewait_sock_slab_name;
1429 }
1412 } 1430 }
1413 1431
1414 write_lock(&proto_list_lock); 1432 write_lock(&proto_list_lock);
@@ -1417,6 +1435,13 @@ int proto_register(struct proto *prot, int alloc_slab)
1417 rc = 0; 1435 rc = 0;
1418out: 1436out:
1419 return rc; 1437 return rc;
1438out_free_timewait_sock_slab_name:
1439 kfree(timewait_sock_slab_name);
1440out_free_request_sock_slab:
1441 if (prot->rsk_prot && prot->rsk_prot->slab) {
1442 kmem_cache_destroy(prot->rsk_prot->slab);
1443 prot->rsk_prot->slab = NULL;
1444 }
1420out_free_request_sock_slab_name: 1445out_free_request_sock_slab_name:
1421 kfree(request_sock_slab_name); 1446 kfree(request_sock_slab_name);
1422out_free_sock_slab: 1447out_free_sock_slab:
@@ -1444,6 +1469,14 @@ void proto_unregister(struct proto *prot)
1444 prot->rsk_prot->slab = NULL; 1469 prot->rsk_prot->slab = NULL;
1445 } 1470 }
1446 1471
1472 if (prot->twsk_slab != NULL) {
1473 const char *name = kmem_cache_name(prot->twsk_slab);
1474
1475 kmem_cache_destroy(prot->twsk_slab);
1476 kfree(name);
1477 prot->twsk_slab = NULL;
1478 }
1479
1447 list_del(&prot->node); 1480 list_del(&prot->node);
1448 write_unlock(&proto_list_lock); 1481 write_unlock(&proto_list_lock);
1449} 1482}