aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorLi Zefan <lizefan@huawei.com>2013-01-09 22:49:27 -0500
committerTejun Heo <tj@kernel.org>2013-01-10 15:10:31 -0500
commit0ac801fe07374148714b5ef53df90ac5b1673c0c (patch)
treeaad528311f4d876c0b8e3750d9cb7b0e072b2935 /kernel/cgroup.c
parent799105d514384b80cbe3182dbcb4ed30aa07e1f5 (diff)
cgroup: use new hashtable implementation
Switch cgroup to use the new hashtable implementation. No functional changes. Signed-off-by: Li Zefan <lizefan@huawei.com> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c92
1 files changed, 39 insertions, 53 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 6643f7053454..54b39081ac04 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -52,7 +52,7 @@
52#include <linux/module.h> 52#include <linux/module.h>
53#include <linux/delayacct.h> 53#include <linux/delayacct.h>
54#include <linux/cgroupstats.h> 54#include <linux/cgroupstats.h>
55#include <linux/hash.h> 55#include <linux/hashtable.h>
56#include <linux/namei.h> 56#include <linux/namei.h>
57#include <linux/pid_namespace.h> 57#include <linux/pid_namespace.h>
58#include <linux/idr.h> 58#include <linux/idr.h>
@@ -376,22 +376,18 @@ static int css_set_count;
376 * account cgroups in empty hierarchies. 376 * account cgroups in empty hierarchies.
377 */ 377 */
378#define CSS_SET_HASH_BITS 7 378#define CSS_SET_HASH_BITS 7
379#define CSS_SET_TABLE_SIZE (1 << CSS_SET_HASH_BITS) 379static DEFINE_HASHTABLE(css_set_table, CSS_SET_HASH_BITS);
380static struct hlist_head css_set_table[CSS_SET_TABLE_SIZE];
381 380
382static struct hlist_head *css_set_hash(struct cgroup_subsys_state *css[]) 381static unsigned long css_set_hash(struct cgroup_subsys_state *css[])
383{ 382{
384 int i; 383 int i;
385 int index; 384 unsigned long key = 0UL;
386 unsigned long tmp = 0UL;
387 385
388 for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) 386 for (i = 0; i < CGROUP_SUBSYS_COUNT; i++)
389 tmp += (unsigned long)css[i]; 387 key += (unsigned long)css[i];
390 tmp = (tmp >> 16) ^ tmp; 388 key = (key >> 16) ^ key;
391 389
392 index = hash_long(tmp, CSS_SET_HASH_BITS); 390 return key;
393
394 return &css_set_table[index];
395} 391}
396 392
397/* We don't maintain the lists running through each css_set to its 393/* We don't maintain the lists running through each css_set to its
@@ -418,7 +414,7 @@ static void __put_css_set(struct css_set *cg, int taskexit)
418 } 414 }
419 415
420 /* This css_set is dead. unlink it and release cgroup refcounts */ 416 /* This css_set is dead. unlink it and release cgroup refcounts */
421 hlist_del(&cg->hlist); 417 hash_del(&cg->hlist);
422 css_set_count--; 418 css_set_count--;
423 419
424 list_for_each_entry_safe(link, saved_link, &cg->cg_links, 420 list_for_each_entry_safe(link, saved_link, &cg->cg_links,
@@ -550,9 +546,9 @@ static struct css_set *find_existing_css_set(
550{ 546{
551 int i; 547 int i;
552 struct cgroupfs_root *root = cgrp->root; 548 struct cgroupfs_root *root = cgrp->root;
553 struct hlist_head *hhead;
554 struct hlist_node *node; 549 struct hlist_node *node;
555 struct css_set *cg; 550 struct css_set *cg;
551 unsigned long key;
556 552
557 /* 553 /*
558 * Build the set of subsystem state objects that we want to see in the 554 * Build the set of subsystem state objects that we want to see in the
@@ -572,8 +568,8 @@ static struct css_set *find_existing_css_set(
572 } 568 }
573 } 569 }
574 570
575 hhead = css_set_hash(template); 571 key = css_set_hash(template);
576 hlist_for_each_entry(cg, node, hhead, hlist) { 572 hash_for_each_possible(css_set_table, cg, node, hlist, key) {
577 if (!compare_css_sets(cg, oldcg, cgrp, template)) 573 if (!compare_css_sets(cg, oldcg, cgrp, template))
578 continue; 574 continue;
579 575
@@ -657,8 +653,8 @@ static struct css_set *find_css_set(
657 653
658 struct list_head tmp_cg_links; 654 struct list_head tmp_cg_links;
659 655
660 struct hlist_head *hhead;
661 struct cg_cgroup_link *link; 656 struct cg_cgroup_link *link;
657 unsigned long key;
662 658
663 /* First see if we already have a cgroup group that matches 659 /* First see if we already have a cgroup group that matches
664 * the desired set */ 660 * the desired set */
@@ -704,8 +700,8 @@ static struct css_set *find_css_set(
704 css_set_count++; 700 css_set_count++;
705 701
706 /* Add this cgroup group to the hash table */ 702 /* Add this cgroup group to the hash table */
707 hhead = css_set_hash(res->subsys); 703 key = css_set_hash(res->subsys);
708 hlist_add_head(&res->hlist, hhead); 704 hash_add(css_set_table, &res->hlist, key);
709 705
710 write_unlock(&css_set_lock); 706 write_unlock(&css_set_lock);
711 707
@@ -1597,6 +1593,8 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
1597 struct cgroupfs_root *existing_root; 1593 struct cgroupfs_root *existing_root;
1598 const struct cred *cred; 1594 const struct cred *cred;
1599 int i; 1595 int i;
1596 struct hlist_node *node;
1597 struct css_set *cg;
1600 1598
1601 BUG_ON(sb->s_root != NULL); 1599 BUG_ON(sb->s_root != NULL);
1602 1600
@@ -1650,14 +1648,8 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
1650 /* Link the top cgroup in this hierarchy into all 1648 /* Link the top cgroup in this hierarchy into all
1651 * the css_set objects */ 1649 * the css_set objects */
1652 write_lock(&css_set_lock); 1650 write_lock(&css_set_lock);
1653 for (i = 0; i < CSS_SET_TABLE_SIZE; i++) { 1651 hash_for_each(css_set_table, i, node, cg, hlist)
1654 struct hlist_head *hhead = &css_set_table[i]; 1652 link_css_set(&tmp_cg_links, cg, root_cgrp);
1655 struct hlist_node *node;
1656 struct css_set *cg;
1657
1658 hlist_for_each_entry(cg, node, hhead, hlist)
1659 link_css_set(&tmp_cg_links, cg, root_cgrp);
1660 }
1661 write_unlock(&css_set_lock); 1653 write_unlock(&css_set_lock);
1662 1654
1663 free_cg_links(&tmp_cg_links); 1655 free_cg_links(&tmp_cg_links);
@@ -4464,6 +4456,9 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
4464{ 4456{
4465 struct cgroup_subsys_state *css; 4457 struct cgroup_subsys_state *css;
4466 int i, ret; 4458 int i, ret;
4459 struct hlist_node *node, *tmp;
4460 struct css_set *cg;
4461 unsigned long key;
4467 4462
4468 /* check name and function validity */ 4463 /* check name and function validity */
4469 if (ss->name == NULL || strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN || 4464 if (ss->name == NULL || strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN ||
@@ -4529,23 +4524,17 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
4529 * this is all done under the css_set_lock. 4524 * this is all done under the css_set_lock.
4530 */ 4525 */
4531 write_lock(&css_set_lock); 4526 write_lock(&css_set_lock);
4532 for (i = 0; i < CSS_SET_TABLE_SIZE; i++) { 4527 hash_for_each_safe(css_set_table, i, node, tmp, cg, hlist) {
4533 struct css_set *cg; 4528 /* skip entries that we already rehashed */
4534 struct hlist_node *node, *tmp; 4529 if (cg->subsys[ss->subsys_id])
4535 struct hlist_head *bucket = &css_set_table[i], *new_bucket; 4530 continue;
4536 4531 /* remove existing entry */
4537 hlist_for_each_entry_safe(cg, node, tmp, bucket, hlist) { 4532 hash_del(&cg->hlist);
4538 /* skip entries that we already rehashed */ 4533 /* set new value */
4539 if (cg->subsys[ss->subsys_id]) 4534 cg->subsys[ss->subsys_id] = css;
4540 continue; 4535 /* recompute hash and restore entry */
4541 /* remove existing entry */ 4536 key = css_set_hash(cg->subsys);
4542 hlist_del(&cg->hlist); 4537 hash_add(css_set_table, node, key);
4543 /* set new value */
4544 cg->subsys[ss->subsys_id] = css;
4545 /* recompute hash and restore entry */
4546 new_bucket = css_set_hash(cg->subsys);
4547 hlist_add_head(&cg->hlist, new_bucket);
4548 }
4549 } 4538 }
4550 write_unlock(&css_set_lock); 4539 write_unlock(&css_set_lock);
4551 4540
@@ -4577,7 +4566,6 @@ EXPORT_SYMBOL_GPL(cgroup_load_subsys);
4577void cgroup_unload_subsys(struct cgroup_subsys *ss) 4566void cgroup_unload_subsys(struct cgroup_subsys *ss)
4578{ 4567{
4579 struct cg_cgroup_link *link; 4568 struct cg_cgroup_link *link;
4580 struct hlist_head *hhead;
4581 4569
4582 BUG_ON(ss->module == NULL); 4570 BUG_ON(ss->module == NULL);
4583 4571
@@ -4611,11 +4599,12 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
4611 write_lock(&css_set_lock); 4599 write_lock(&css_set_lock);
4612 list_for_each_entry(link, &dummytop->css_sets, cgrp_link_list) { 4600 list_for_each_entry(link, &dummytop->css_sets, cgrp_link_list) {
4613 struct css_set *cg = link->cg; 4601 struct css_set *cg = link->cg;
4602 unsigned long key;
4614 4603
4615 hlist_del(&cg->hlist); 4604 hash_del(&cg->hlist);
4616 cg->subsys[ss->subsys_id] = NULL; 4605 cg->subsys[ss->subsys_id] = NULL;
4617 hhead = css_set_hash(cg->subsys); 4606 key = css_set_hash(cg->subsys);
4618 hlist_add_head(&cg->hlist, hhead); 4607 hash_add(css_set_table, &cg->hlist, key);
4619 } 4608 }
4620 write_unlock(&css_set_lock); 4609 write_unlock(&css_set_lock);
4621 4610
@@ -4657,9 +4646,6 @@ int __init cgroup_init_early(void)
4657 list_add(&init_css_set_link.cg_link_list, 4646 list_add(&init_css_set_link.cg_link_list,
4658 &init_css_set.cg_links); 4647 &init_css_set.cg_links);
4659 4648
4660 for (i = 0; i < CSS_SET_TABLE_SIZE; i++)
4661 INIT_HLIST_HEAD(&css_set_table[i]);
4662
4663 for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { 4649 for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
4664 struct cgroup_subsys *ss = subsys[i]; 4650 struct cgroup_subsys *ss = subsys[i];
4665 4651
@@ -4693,7 +4679,7 @@ int __init cgroup_init(void)
4693{ 4679{
4694 int err; 4680 int err;
4695 int i; 4681 int i;
4696 struct hlist_head *hhead; 4682 unsigned long key;
4697 4683
4698 err = bdi_init(&cgroup_backing_dev_info); 4684 err = bdi_init(&cgroup_backing_dev_info);
4699 if (err) 4685 if (err)
@@ -4712,8 +4698,8 @@ int __init cgroup_init(void)
4712 } 4698 }
4713 4699
4714 /* Add init_css_set to the hash table */ 4700 /* Add init_css_set to the hash table */
4715 hhead = css_set_hash(init_css_set.subsys); 4701 key = css_set_hash(init_css_set.subsys);
4716 hlist_add_head(&init_css_set.hlist, hhead); 4702 hash_add(css_set_table, &init_css_set.hlist, key);
4717 BUG_ON(!init_root_id(&rootnode)); 4703 BUG_ON(!init_root_id(&rootnode));
4718 4704
4719 cgroup_kobj = kobject_create_and_add("cgroup", fs_kobj); 4705 cgroup_kobj = kobject_create_and_add("cgroup", fs_kobj);