Commit 115085ea authored by Oleg Nesterov's avatar Oleg Nesterov Committed by Linus Torvalds

[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: default avatarOleg 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: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 128fb956
...@@ -15,12 +15,6 @@ ...@@ -15,12 +15,6 @@
extern struct kmem_cache *taskstats_cache; extern struct kmem_cache *taskstats_cache;
extern struct mutex taskstats_exit_mutex; 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) static inline void taskstats_tgid_init(struct signal_struct *sig)
{ {
sig->stats = NULL; sig->stats = NULL;
...@@ -54,17 +48,10 @@ static inline void taskstats_tgid_free(struct signal_struct *sig) ...@@ -54,17 +48,10 @@ static inline void taskstats_tgid_free(struct signal_struct *sig)
kmem_cache_free(taskstats_cache, sig->stats); kmem_cache_free(taskstats_cache, sig->stats);
} }
extern void taskstats_exit_alloc(struct taskstats **, unsigned int *); extern void taskstats_exit(struct task_struct *, int group_dead);
extern void taskstats_exit_send(struct task_struct *, struct taskstats *, int, unsigned int);
extern void taskstats_init_early(void); extern void taskstats_init_early(void);
#else #else
static inline void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu) static inline void taskstats_exit(struct task_struct *tsk, int group_dead)
{}
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_tgid_init(struct signal_struct *sig) static inline void taskstats_tgid_init(struct signal_struct *sig)
{} {}
......
...@@ -850,9 +850,7 @@ static void exit_notify(struct task_struct *tsk) ...@@ -850,9 +850,7 @@ static void exit_notify(struct task_struct *tsk)
fastcall NORET_TYPE void do_exit(long code) fastcall NORET_TYPE void do_exit(long code)
{ {
struct task_struct *tsk = current; struct task_struct *tsk = current;
struct taskstats *tidstats;
int group_dead; int group_dead;
unsigned int mycpu;
profile_task_exit(tsk); profile_task_exit(tsk);
...@@ -890,8 +888,6 @@ fastcall NORET_TYPE void do_exit(long code) ...@@ -890,8 +888,6 @@ fastcall NORET_TYPE void do_exit(long code)
current->comm, current->pid, current->comm, current->pid,
preempt_count()); preempt_count());
taskstats_exit_alloc(&tidstats, &mycpu);
acct_update_integrals(tsk); acct_update_integrals(tsk);
if (tsk->mm) { if (tsk->mm) {
update_hiwater_rss(tsk->mm); update_hiwater_rss(tsk->mm);
...@@ -911,8 +907,8 @@ fastcall NORET_TYPE void do_exit(long code) ...@@ -911,8 +907,8 @@ fastcall NORET_TYPE void do_exit(long code)
#endif #endif
if (unlikely(tsk->audit_context)) if (unlikely(tsk->audit_context))
audit_free(tsk); audit_free(tsk);
taskstats_exit_send(tsk, tidstats, group_dead, mycpu);
taskstats_exit_free(tidstats); taskstats_exit(tsk, group_dead);
exit_mm(tsk); exit_mm(tsk);
......
...@@ -119,10 +119,10 @@ static int send_reply(struct sk_buff *skb, pid_t pid) ...@@ -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 * 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 genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data);
struct listener_list *listeners;
struct listener *s, *tmp; struct listener *s, *tmp;
struct sk_buff *skb_next, *skb_cur = skb; struct sk_buff *skb_next, *skb_cur = skb;
void *reply = genlmsg_data(genlhdr); void *reply = genlmsg_data(genlhdr);
...@@ -135,7 +135,6 @@ static void send_cpu_listeners(struct sk_buff *skb, unsigned int cpu) ...@@ -135,7 +135,6 @@ static void send_cpu_listeners(struct sk_buff *skb, unsigned int cpu)
} }
rc = 0; rc = 0;
listeners = &per_cpu(listener_array, cpu);
down_read(&listeners->sem); down_read(&listeners->sem);
list_for_each_entry(s, &listeners->list, list) { list_for_each_entry(s, &listeners->list, list) {
skb_next = NULL; skb_next = NULL;
...@@ -413,28 +412,12 @@ err: ...@@ -413,28 +412,12 @@ err:
return rc; 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 */ /* Send pid data out on exit */
void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats, void taskstats_exit(struct task_struct *tsk, int group_dead)
int group_dead, unsigned int mycpu)
{ {
int rc; int rc;
struct listener_list *listeners;
struct taskstats *tidstats;
struct sk_buff *rep_skb; struct sk_buff *rep_skb;
void *reply; void *reply;
size_t size; size_t size;
...@@ -458,12 +441,17 @@ void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats, ...@@ -458,12 +441,17 @@ void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats,
fill_tgid_exit(tsk); 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) if (!tidstats)
return; return;
rc = prepare_reply(NULL, TASKSTATS_CMD_NEW, &rep_skb, &reply, size); rc = prepare_reply(NULL, TASKSTATS_CMD_NEW, &rep_skb, &reply, size);
if (rc < 0) if (rc < 0)
goto ret; goto free_stats;
rc = fill_pid(tsk->pid, tsk, tidstats); rc = fill_pid(tsk->pid, tsk, tidstats);
if (rc < 0) if (rc < 0)
...@@ -492,15 +480,16 @@ void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats, ...@@ -492,15 +480,16 @@ void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats,
nla_nest_end(rep_skb, na); nla_nest_end(rep_skb, na);
send: send:
send_cpu_listeners(rep_skb, mycpu); send_cpu_listeners(rep_skb, listeners);
free_stats:
kmem_cache_free(taskstats_cache, tidstats);
return; return;
nla_put_failure: nla_put_failure:
genlmsg_cancel(rep_skb, reply); genlmsg_cancel(rep_skb, reply);
err_skb: err_skb:
nlmsg_free(rep_skb); nlmsg_free(rep_skb);
ret: goto free_stats;
return;
} }
static struct genl_ops taskstats_ops = { static struct genl_ops taskstats_ops = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment