diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/cgroup.h | 50 | ||||
-rw-r--r-- | include/linux/idr.h | 1 |
2 files changed, 51 insertions, 0 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 788c4964c142..9a23bb098205 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/cgroupstats.h> | 15 | #include <linux/cgroupstats.h> |
16 | #include <linux/prio_heap.h> | 16 | #include <linux/prio_heap.h> |
17 | #include <linux/rwsem.h> | 17 | #include <linux/rwsem.h> |
18 | #include <linux/idr.h> | ||
18 | 19 | ||
19 | #ifdef CONFIG_CGROUPS | 20 | #ifdef CONFIG_CGROUPS |
20 | 21 | ||
@@ -22,6 +23,7 @@ struct cgroupfs_root; | |||
22 | struct cgroup_subsys; | 23 | struct cgroup_subsys; |
23 | struct inode; | 24 | struct inode; |
24 | struct cgroup; | 25 | struct cgroup; |
26 | struct css_id; | ||
25 | 27 | ||
26 | extern int cgroup_init_early(void); | 28 | extern int cgroup_init_early(void); |
27 | extern int cgroup_init(void); | 29 | extern int cgroup_init(void); |
@@ -63,6 +65,8 @@ struct cgroup_subsys_state { | |||
63 | atomic_t refcnt; | 65 | atomic_t refcnt; |
64 | 66 | ||
65 | unsigned long flags; | 67 | unsigned long flags; |
68 | /* ID for this css, if possible */ | ||
69 | struct css_id *id; | ||
66 | }; | 70 | }; |
67 | 71 | ||
68 | /* bits in struct cgroup_subsys_state flags field */ | 72 | /* bits in struct cgroup_subsys_state flags field */ |
@@ -373,6 +377,11 @@ struct cgroup_subsys { | |||
373 | int active; | 377 | int active; |
374 | int disabled; | 378 | int disabled; |
375 | int early_init; | 379 | int early_init; |
380 | /* | ||
381 | * True if this subsys uses ID. ID is not available before cgroup_init() | ||
382 | * (not available in early_init time.) | ||
383 | */ | ||
384 | bool use_id; | ||
376 | #define MAX_CGROUP_TYPE_NAMELEN 32 | 385 | #define MAX_CGROUP_TYPE_NAMELEN 32 |
377 | const char *name; | 386 | const char *name; |
378 | 387 | ||
@@ -395,6 +404,9 @@ struct cgroup_subsys { | |||
395 | */ | 404 | */ |
396 | struct cgroupfs_root *root; | 405 | struct cgroupfs_root *root; |
397 | struct list_head sibling; | 406 | struct list_head sibling; |
407 | /* used when use_id == true */ | ||
408 | struct idr idr; | ||
409 | spinlock_t id_lock; | ||
398 | }; | 410 | }; |
399 | 411 | ||
400 | #define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys; | 412 | #define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys; |
@@ -450,6 +462,44 @@ void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it); | |||
450 | int cgroup_scan_tasks(struct cgroup_scanner *scan); | 462 | int cgroup_scan_tasks(struct cgroup_scanner *scan); |
451 | int cgroup_attach_task(struct cgroup *, struct task_struct *); | 463 | int cgroup_attach_task(struct cgroup *, struct task_struct *); |
452 | 464 | ||
465 | /* | ||
466 | * CSS ID is ID for cgroup_subsys_state structs under subsys. This only works | ||
467 | * if cgroup_subsys.use_id == true. It can be used for looking up and scanning. | ||
468 | * CSS ID is assigned at cgroup allocation (create) automatically | ||
469 | * and removed when subsys calls free_css_id() function. This is because | ||
470 | * the lifetime of cgroup_subsys_state is subsys's matter. | ||
471 | * | ||
472 | * Looking up and scanning function should be called under rcu_read_lock(). | ||
473 | * Taking cgroup_mutex()/hierarchy_mutex() is not necessary for following calls. | ||
474 | * But the css returned by this routine can be "not populated yet" or "being | ||
475 | * destroyed". The caller should check css and cgroup's status. | ||
476 | */ | ||
477 | |||
478 | /* | ||
479 | * Typically Called at ->destroy(), or somewhere the subsys frees | ||
480 | * cgroup_subsys_state. | ||
481 | */ | ||
482 | void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css); | ||
483 | |||
484 | /* Find a cgroup_subsys_state which has given ID */ | ||
485 | |||
486 | struct cgroup_subsys_state *css_lookup(struct cgroup_subsys *ss, int id); | ||
487 | |||
488 | /* | ||
489 | * Get a cgroup whose id is greater than or equal to id under tree of root. | ||
490 | * Returning a cgroup_subsys_state or NULL. | ||
491 | */ | ||
492 | struct cgroup_subsys_state *css_get_next(struct cgroup_subsys *ss, int id, | ||
493 | struct cgroup_subsys_state *root, int *foundid); | ||
494 | |||
495 | /* Returns true if root is ancestor of cg */ | ||
496 | bool css_is_ancestor(struct cgroup_subsys_state *cg, | ||
497 | struct cgroup_subsys_state *root); | ||
498 | |||
499 | /* Get id and depth of css */ | ||
500 | unsigned short css_id(struct cgroup_subsys_state *css); | ||
501 | unsigned short css_depth(struct cgroup_subsys_state *css); | ||
502 | |||
453 | #else /* !CONFIG_CGROUPS */ | 503 | #else /* !CONFIG_CGROUPS */ |
454 | 504 | ||
455 | static inline int cgroup_init_early(void) { return 0; } | 505 | static inline int cgroup_init_early(void) { return 0; } |
diff --git a/include/linux/idr.h b/include/linux/idr.h index dd846df8cd32..e968db71e33a 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h | |||
@@ -106,6 +106,7 @@ int idr_get_new(struct idr *idp, void *ptr, int *id); | |||
106 | int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id); | 106 | int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id); |
107 | int idr_for_each(struct idr *idp, | 107 | int idr_for_each(struct idr *idp, |
108 | int (*fn)(int id, void *p, void *data), void *data); | 108 | int (*fn)(int id, void *p, void *data), void *data); |
109 | void *idr_get_next(struct idr *idp, int *nextid); | ||
109 | void *idr_replace(struct idr *idp, void *ptr, int id); | 110 | void *idr_replace(struct idr *idp, void *ptr, int id); |
110 | void idr_remove(struct idr *idp, int id); | 111 | void idr_remove(struct idr *idp, int id); |
111 | void idr_remove_all(struct idr *idp); | 112 | void idr_remove_all(struct idr *idp); |