diff options
Diffstat (limited to 'kernel/kthread.c')
-rw-r--r-- | kernel/kthread.c | 66 |
1 files changed, 62 insertions, 4 deletions
diff --git a/kernel/kthread.c b/kernel/kthread.c index ba3992c8c375..8af313081b0d 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/freezer.h> | 20 | #include <linux/freezer.h> |
21 | #include <linux/ptrace.h> | 21 | #include <linux/ptrace.h> |
22 | #include <linux/uaccess.h> | 22 | #include <linux/uaccess.h> |
23 | #include <linux/cgroup.h> | ||
24 | #include <trace/events/sched.h> | 23 | #include <trace/events/sched.h> |
25 | 24 | ||
26 | static DEFINE_SPINLOCK(kthread_create_lock); | 25 | static DEFINE_SPINLOCK(kthread_create_lock); |
@@ -47,6 +46,9 @@ struct kthread { | |||
47 | void *data; | 46 | void *data; |
48 | struct completion parked; | 47 | struct completion parked; |
49 | struct completion exited; | 48 | struct completion exited; |
49 | #ifdef CONFIG_BLK_CGROUP | ||
50 | struct cgroup_subsys_state *blkcg_css; | ||
51 | #endif | ||
50 | }; | 52 | }; |
51 | 53 | ||
52 | enum KTHREAD_BITS { | 54 | enum KTHREAD_BITS { |
@@ -74,11 +76,17 @@ static inline struct kthread *to_kthread(struct task_struct *k) | |||
74 | 76 | ||
75 | void free_kthread_struct(struct task_struct *k) | 77 | void free_kthread_struct(struct task_struct *k) |
76 | { | 78 | { |
79 | struct kthread *kthread; | ||
80 | |||
77 | /* | 81 | /* |
78 | * Can be NULL if this kthread was created by kernel_thread() | 82 | * Can be NULL if this kthread was created by kernel_thread() |
79 | * or if kmalloc() in kthread() failed. | 83 | * or if kmalloc() in kthread() failed. |
80 | */ | 84 | */ |
81 | kfree(to_kthread(k)); | 85 | kthread = to_kthread(k); |
86 | #ifdef CONFIG_BLK_CGROUP | ||
87 | WARN_ON_ONCE(kthread && kthread->blkcg_css); | ||
88 | #endif | ||
89 | kfree(kthread); | ||
82 | } | 90 | } |
83 | 91 | ||
84 | /** | 92 | /** |
@@ -196,7 +204,7 @@ static int kthread(void *_create) | |||
196 | struct kthread *self; | 204 | struct kthread *self; |
197 | int ret; | 205 | int ret; |
198 | 206 | ||
199 | self = kmalloc(sizeof(*self), GFP_KERNEL); | 207 | self = kzalloc(sizeof(*self), GFP_KERNEL); |
200 | set_kthread_struct(self); | 208 | set_kthread_struct(self); |
201 | 209 | ||
202 | /* If user was SIGKILLed, I release the structure. */ | 210 | /* If user was SIGKILLed, I release the structure. */ |
@@ -212,7 +220,6 @@ static int kthread(void *_create) | |||
212 | do_exit(-ENOMEM); | 220 | do_exit(-ENOMEM); |
213 | } | 221 | } |
214 | 222 | ||
215 | self->flags = 0; | ||
216 | self->data = data; | 223 | self->data = data; |
217 | init_completion(&self->exited); | 224 | init_completion(&self->exited); |
218 | init_completion(&self->parked); | 225 | init_completion(&self->parked); |
@@ -1152,3 +1159,54 @@ void kthread_destroy_worker(struct kthread_worker *worker) | |||
1152 | kfree(worker); | 1159 | kfree(worker); |
1153 | } | 1160 | } |
1154 | EXPORT_SYMBOL(kthread_destroy_worker); | 1161 | EXPORT_SYMBOL(kthread_destroy_worker); |
1162 | |||
1163 | #ifdef CONFIG_BLK_CGROUP | ||
1164 | /** | ||
1165 | * kthread_associate_blkcg - associate blkcg to current kthread | ||
1166 | * @css: the cgroup info | ||
1167 | * | ||
1168 | * Current thread must be a kthread. The thread is running jobs on behalf of | ||
1169 | * other threads. In some cases, we expect the jobs attach cgroup info of | ||
1170 | * original threads instead of that of current thread. This function stores | ||
1171 | * original thread's cgroup info in current kthread context for later | ||
1172 | * retrieval. | ||
1173 | */ | ||
1174 | void kthread_associate_blkcg(struct cgroup_subsys_state *css) | ||
1175 | { | ||
1176 | struct kthread *kthread; | ||
1177 | |||
1178 | if (!(current->flags & PF_KTHREAD)) | ||
1179 | return; | ||
1180 | kthread = to_kthread(current); | ||
1181 | if (!kthread) | ||
1182 | return; | ||
1183 | |||
1184 | if (kthread->blkcg_css) { | ||
1185 | css_put(kthread->blkcg_css); | ||
1186 | kthread->blkcg_css = NULL; | ||
1187 | } | ||
1188 | if (css) { | ||
1189 | css_get(css); | ||
1190 | kthread->blkcg_css = css; | ||
1191 | } | ||
1192 | } | ||
1193 | EXPORT_SYMBOL(kthread_associate_blkcg); | ||
1194 | |||
1195 | /** | ||
1196 | * kthread_blkcg - get associated blkcg css of current kthread | ||
1197 | * | ||
1198 | * Current thread must be a kthread. | ||
1199 | */ | ||
1200 | struct cgroup_subsys_state *kthread_blkcg(void) | ||
1201 | { | ||
1202 | struct kthread *kthread; | ||
1203 | |||
1204 | if (current->flags & PF_KTHREAD) { | ||
1205 | kthread = to_kthread(current); | ||
1206 | if (kthread) | ||
1207 | return kthread->blkcg_css; | ||
1208 | } | ||
1209 | return NULL; | ||
1210 | } | ||
1211 | EXPORT_SYMBOL(kthread_blkcg); | ||
1212 | #endif | ||