+ per-task-delay-accounting-taskstats-interface-fix-exit-race-in-per-task-delay-accounting.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled

     Fix exit race in per-task-delay-accounting

has been added to the -mm tree.  Its filename is

     per-task-delay-accounting-taskstats-interface-fix-exit-race-in-per-task-delay-accounting.patch

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

------------------------------------------------------
Subject: Fix exit race in per-task-delay-accounting
From: Balbir Singh <balbir@xxxxxxxxxx>


Fix a race in per-task-delay-accounting.  This race was reported by Jay
Lan.  I tested the patch using cerebrus test control system for eight hours
with getdelays running on the side (for both push and pull of delay
statistics).

It fixed the problem that Jay Lan saw.

Here's an explanation of the race condition

Consider tasks of the same thread group exiting, lets call them T1 and T2

T1                          T2

CPU0                        CPU1
=====                       =====

do_exit()
...                        do_exit()
taskstats_exit_send()                ...
                           taskstats_exit_send()
                           	fill_tgid()
                                delayacct_add_tsk()
delayacct_tsk_exit()            ....
                                __delayacct_add_tsk()

While T1 is yet to be removed from the thread group.  T1->delays is set to
NULL between delayacct_add_tsk() and __delayacct_add_tsk() call.

When T2 looks for threads in the thread group, it finds T1 and tries to
collect stats for it.  When we get to the spin_lock() in
__delayacct_add_tsk(), we find T1->delays is a NULL pointer.

Signed-off-by: Balbir Singh <balbir@xxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 include/linux/taskstats_kern.h |    1 +
 kernel/delayacct.c             |    5 ++++-
 kernel/taskstats.c             |    5 ++++-
 3 files changed, 9 insertions(+), 2 deletions(-)

diff -puN include/linux/taskstats_kern.h~per-task-delay-accounting-taskstats-interface-fix-exit-race-in-per-task-delay-accounting include/linux/taskstats_kern.h
--- a/include/linux/taskstats_kern.h~per-task-delay-accounting-taskstats-interface-fix-exit-race-in-per-task-delay-accounting
+++ a/include/linux/taskstats_kern.h
@@ -17,6 +17,7 @@ enum {
 
 #ifdef CONFIG_TASKSTATS
 extern kmem_cache_t *taskstats_cache;
+extern struct mutex taskstats_exit_mutex;
 
 static inline void taskstats_exit_alloc(struct taskstats **ptidstats,
 					struct taskstats **ptgidstats)
diff -puN kernel/delayacct.c~per-task-delay-accounting-taskstats-interface-fix-exit-race-in-per-task-delay-accounting kernel/delayacct.c
--- a/kernel/delayacct.c~per-task-delay-accounting-taskstats-interface-fix-exit-race-in-per-task-delay-accounting
+++ a/kernel/delayacct.c
@@ -48,8 +48,11 @@ void __delayacct_tsk_init(struct task_st
 
 void __delayacct_tsk_exit(struct task_struct *tsk)
 {
-	kmem_cache_free(delayacct_cache, tsk->delays);
+	struct task_delay_info *delays = tsk->delays;
+	mutex_lock(&taskstats_exit_mutex);
 	tsk->delays = NULL;
+	mutex_unlock(&taskstats_exit_mutex);
+	kmem_cache_free(delayacct_cache, delays);
 }
 
 /*
diff -puN kernel/taskstats.c~per-task-delay-accounting-taskstats-interface-fix-exit-race-in-per-task-delay-accounting kernel/taskstats.c
--- a/kernel/taskstats.c~per-task-delay-accounting-taskstats-interface-fix-exit-race-in-per-task-delay-accounting
+++ a/kernel/taskstats.c
@@ -24,7 +24,7 @@
 static DEFINE_PER_CPU(__u32, taskstats_seqnum) = { 0 };
 static int family_registered = 0;
 kmem_cache_t *taskstats_cache;
-static DEFINE_MUTEX(taskstats_exit_mutex);
+DEFINE_MUTEX(taskstats_exit_mutex);
 
 static struct genl_family family = {
 	.id		= GENL_ID_GENERATE,
@@ -183,6 +183,7 @@ static int taskstats_send_stats(struct s
 	if (rc < 0)
 		return rc;
 
+	mutex_lock(&taskstats_exit_mutex);
 	if (info->attrs[TASKSTATS_CMD_ATTR_PID]) {
 		u32 pid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_PID]);
 		rc = fill_pid(pid, NULL, &stats);
@@ -208,6 +209,7 @@ static int taskstats_send_stats(struct s
 		goto err;
 	}
 
+	mutex_unlock(&taskstats_exit_mutex);
 	nla_nest_end(rep_skb, na);
 
 	return send_reply(rep_skb, info->snd_pid, TASKSTATS_MSG_UNICAST);
@@ -216,6 +218,7 @@ nla_put_failure:
 	return genlmsg_cancel(rep_skb, reply);
 err:
 	nlmsg_free(rep_skb);
+	mutex_unlock(&taskstats_exit_mutex);
 	return rc;
 }
 
_

Patches currently in -mm which might be from balbir@xxxxxxxxxx are

fix-dcache-race-during-umount.patch
prune_one_dentry-tweaks.patch
per-task-delay-accounting-setup.patch
per-task-delay-accounting-setup-fix-1.patch
per-task-delay-accounting-setup-fix-2.patch
per-task-delay-accounting-sync-block-i-o-and-swapin-delay-collection.patch
per-task-delay-accounting-sync-block-i-o-and-swapin-delay-collection-fix-1.patch
per-task-delay-accounting-cpu-delay-collection-via-schedstats.patch
per-task-delay-accounting-cpu-delay-collection-via-schedstats-fix-1.patch
per-task-delay-accounting-utilities-for-genetlink-usage.patch
per-task-delay-accounting-taskstats-interface.patch
per-task-delay-accounting-taskstats-interface-fix-1.patch
per-task-delay-accounting-taskstats-interface-fix-2.patch
per-task-delay-accounting-taskstats-interface-fix-exit-race-in-per-task-delay-accounting.patch
per-task-delay-accounting-delay-accounting-usage-of-taskstats-interface.patch
per-task-delay-accounting-delay-accounting-usage-of-taskstats-interface-use-portable-cputime-api-in-__delayacct_add_tsk.patch
per-task-delay-accounting-delay-accounting-usage-of-taskstats-interface-fix-return-value-of-delayacct_add_tsk.patch
per-task-delay-accounting-documentation.patch
per-task-delay-accounting-proc-export-of-aggregated-block-i-o-delays.patch
per-task-delay-accounting-proc-export-of-aggregated-block-i-o-delays-warning-fix.patch
task-watchers-register-per-task-delay-accounting.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux