Messages in this thread | | | Date | Sat, 30 Mar 2013 15:36:00 +0100 | From | Oleg Nesterov <> | Subject | Re: [PATCH 1/3] kthread: implement probe_kthread_data() |
| |
On 03/29, Tejun Heo wrote: > > Implement probe_kthread_data() which returns kthread_data if > accessible. The function is equivalent to kthread_data() except that > the specified @task may not be a kthread ^^^^^^^^^^^^^^^^^^^^^^^^^
This doesn't necessarily mean its ->vfork_done != NULL... but I guess the "false positive" is fine for your purpose.
> or its vfork_done is already > cleared rendering struct kthread inaccessible. > ...
> +/** > + * probe_kthread_data - speculatively version of kthread_data() > + * @task: possible kthread task in question > + * > + * @task could be a kthread task. Return the data value specified when it > + * was created if accessible. If @task isn't a kthread task or its data is > + * inaccessible for any reason, %NULL is returned. This function requires > + * that @task itself is safe to dereference. > + */ > +void *probe_kthread_data(struct task_struct *task) > +{ > + struct kthread *kthread = to_kthread(task); > + void *data = NULL; > + > + probe_kernel_read(&data, &kthread->data, sizeof(data)); > + return data; > +}
OK, but we can simply check ->vfork_done != NULL ?
We do not care if we race with the exiting thread which can clear its ->vfork_done. If it is safe to dereference this @task then kthread is also safe.
kthread-introduce-to_live_kthread.patch in -mm adds the trivial helper,
static inline struct kthread *to_kthread(struct task_struct *k) { return __to_kthread(k->vfork_done); }
static struct kthread *to_live_kthread(struct task_struct *k) { struct completion *vfork = ACCESS_ONCE(k->vfork_done); if (likely(vfork)) return __to_kthread(vfork); return NULL; }
So, perhaps,
voif *kthread_data_safe(struct task_struct *task) { struct kthread *kthread = to_live_kthread(task); return kthread ? kthread->data : NULL; }
?
Oleg.
| |