diff options
Diffstat (limited to 'kernel/taskstats.c')
-rw-r--r-- | kernel/taskstats.c | 41 |
1 files changed, 15 insertions, 26 deletions
diff --git a/kernel/taskstats.c b/kernel/taskstats.c index d9d7c357623..2654886fe05 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 = { |