2 #include <linux/user-return-notifier.h>
3 #include <linux/percpu.h>
4 #include <linux/sched.h>
5 #include <linux/module.h>
7 static DEFINE_PER_CPU(struct hlist_head
, return_notifier_list
);
9 #define URN_LIST_HEAD per_cpu(return_notifier_list, raw_smp_processor_id())
12 * Request a notification when the current cpu returns to userspace. Must be
13 * called in atomic context. The notifier will also be called in atomic
16 void user_return_notifier_register(struct user_return_notifier
*urn
)
18 set_tsk_thread_flag(current
, TIF_USER_RETURN_NOTIFY
);
19 hlist_add_head(&urn
->link
, &URN_LIST_HEAD
);
21 EXPORT_SYMBOL_GPL(user_return_notifier_register
);
24 * Removes a registered user return notifier. Must be called from atomic
25 * context, and from the same cpu registration occured in.
27 void user_return_notifier_unregister(struct user_return_notifier
*urn
)
29 hlist_del(&urn
->link
);
30 if (hlist_empty(&URN_LIST_HEAD
))
31 clear_tsk_thread_flag(current
, TIF_USER_RETURN_NOTIFY
);
33 EXPORT_SYMBOL_GPL(user_return_notifier_unregister
);
35 /* Calls registered user return notifiers */
36 void fire_user_return_notifiers(void)
38 struct user_return_notifier
*urn
;
39 struct hlist_node
*tmp1
, *tmp2
;
40 struct hlist_head
*head
;
42 head
= &get_cpu_var(return_notifier_list
);
43 hlist_for_each_entry_safe(urn
, tmp1
, tmp2
, head
, link
)
44 urn
->on_user_return(urn
);
45 put_cpu_var(return_notifier_list
);