diff options
author | Oleg Nesterov <oleg@tv-sign.ru> | 2006-12-06 20:36:51 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-07 08:39:34 -0800 |
commit | 115085ea0794c0f339be8f9d25505c7f9861d824 (patch) | |
tree | 0b69f20ab8ab53702a4c94c11927e60fa058b509 | |
parent | 128fb95650b3273a8dc9ba5514b6fe7db8ea30bf (diff) | |
download | op-kernel-dev-115085ea0794c0f339be8f9d25505c7f9861d824.zip op-kernel-dev-115085ea0794c0f339be8f9d25505c7f9861d824.tar.gz |
[PATCH] taskstats: cleanup do_exit() path
do_exit:
taskstats_exit_alloc()
...
taskstats_exit_send()
taskstats_exit_free()
I think this is not good, let it be a single function exported to the core
kernel, taskstats_exit(), which does alloc + send + free itself.
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Balbir Singh <balbir@in.ibm.com>
Cc: Shailabh Nagar <nagar@watson.ibm.com>
Cc: Jay Lan <jlan@engr.sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | include/linux/taskstats_kern.h | 17 | ||||
-rw-r--r-- | kernel/exit.c | 8 | ||||
-rw-r--r-- | kernel/taskstats.c | 41 |
3 files changed, 19 insertions, 47 deletions
diff --git a/include/linux/taskstats_kern.h b/include/linux/taskstats_kern.h index ce8a912..f1261a5 100644 --- a/include/linux/taskstats_kern.h +++ b/include/linux/taskstats_kern.h @@ -15,12 +15,6 @@ extern struct kmem_cache *taskstats_cache; extern struct mutex taskstats_exit_mutex; -static inline void taskstats_exit_free(struct taskstats *tidstats) -{ - if (tidstats) - kmem_cache_free(taskstats_cache, tidstats); -} - static inline void taskstats_tgid_init(struct signal_struct *sig) { sig->stats = NULL; @@ -54,17 +48,10 @@ static inline void taskstats_tgid_free(struct signal_struct *sig) kmem_cache_free(taskstats_cache, sig->stats); } -extern void taskstats_exit_alloc(struct taskstats **, unsigned int *); -extern void taskstats_exit_send(struct task_struct *, struct taskstats *, int, unsigned int); +extern void taskstats_exit(struct task_struct *, int group_dead); extern void taskstats_init_early(void); #else -static inline void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu) -{} -static inline void taskstats_exit_free(struct taskstats *ptidstats) -{} -static inline void taskstats_exit_send(struct task_struct *tsk, - struct taskstats *tidstats, - int group_dead, unsigned int cpu) +static inline void taskstats_exit(struct task_struct *tsk, int group_dead) {} static inline void taskstats_tgid_init(struct signal_struct *sig) {} diff --git a/kernel/exit.c b/kernel/exit.c index 06de6c4..4e3f919 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -850,9 +850,7 @@ static void exit_notify(struct task_struct *tsk) fastcall NORET_TYPE void do_exit(long code) { struct task_struct *tsk = current; - struct taskstats *tidstats; int group_dead; - unsigned int mycpu; profile_task_exit(tsk); @@ -890,8 +888,6 @@ fastcall NORET_TYPE void do_exit(long code) current->comm, current->pid, preempt_count()); - taskstats_exit_alloc(&tidstats, &mycpu); - acct_update_integrals(tsk); if (tsk->mm) { update_hiwater_rss(tsk->mm); @@ -911,8 +907,8 @@ fastcall NORET_TYPE void do_exit(long code) #endif if (unlikely(tsk->audit_context)) audit_free(tsk); - taskstats_exit_send(tsk, tidstats, group_dead, mycpu); - taskstats_exit_free(tidstats); + + taskstats_exit(tsk, group_dead); exit_mm(tsk); diff --git a/kernel/taskstats.c b/kernel/taskstats.c index d9d7c35..2654886 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c @@ -119,10 +119,10 @@ static int send_reply(struct sk_buff *skb, pid_t pid) /* * Send taskstats data in @skb to listeners registered for @cpu's exit data */ -static void send_cpu_listeners(struct sk_buff *skb, unsigned int cpu) +static void send_cpu_listeners(struct sk_buff *skb, + struct listener_list *listeners) { struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data); - struct listener_list *listeners; struct listener *s, *tmp; struct sk_buff *skb_next, *skb_cur = skb; void *reply = genlmsg_data(genlhdr); @@ -135,7 +135,6 @@ static void send_cpu_listeners(struct sk_buff *skb, unsigned int cpu) } rc = 0; - listeners = &per_cpu(listener_array, cpu); down_read(&listeners->sem); list_for_each_entry(s, &listeners->list, list) { skb_next = NULL; @@ -413,28 +412,12 @@ err: return rc; } -void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu) -{ - struct listener_list *listeners; - /* - * This is the cpu on which the task is exiting currently and will - * be the one for which the exit event is sent, even if the cpu - * on which this function is running changes later. - */ - *mycpu = raw_smp_processor_id(); - - listeners = &per_cpu(listener_array, *mycpu); - - *ptidstats = NULL; - if (!list_empty(&listeners->list)) - *ptidstats = kmem_cache_zalloc(taskstats_cache, GFP_KERNEL); -} - /* Send pid data out on exit */ -void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats, - int group_dead, unsigned int mycpu) +void taskstats_exit(struct task_struct *tsk, int group_dead) { int rc; + struct listener_list *listeners; + struct taskstats *tidstats; struct sk_buff *rep_skb; void *reply; size_t size; @@ -458,12 +441,17 @@ void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats, fill_tgid_exit(tsk); } + listeners = &__raw_get_cpu_var(listener_array); + if (list_empty(&listeners->list)) + return; + + tidstats = kmem_cache_zalloc(taskstats_cache, GFP_KERNEL); if (!tidstats) return; rc = prepare_reply(NULL, TASKSTATS_CMD_NEW, &rep_skb, &reply, size); if (rc < 0) - goto ret; + goto free_stats; rc = fill_pid(tsk->pid, tsk, tidstats); if (rc < 0) @@ -492,15 +480,16 @@ void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats, nla_nest_end(rep_skb, na); send: - send_cpu_listeners(rep_skb, mycpu); + send_cpu_listeners(rep_skb, listeners); +free_stats: + kmem_cache_free(taskstats_cache, tidstats); return; nla_put_failure: genlmsg_cancel(rep_skb, reply); err_skb: nlmsg_free(rep_skb); -ret: - return; + goto free_stats; } static struct genl_ops taskstats_ops = { |