Linux-MIPS Archive on lore.kernel.org
 help / Atom feed
From: <yhb@ruijie.com.cn>
To: <ralf@linux-mips.org>
Cc: <linux-mips@linux-mips.org>
Subject: MIPS: We need to clear MMU contexts of all other processes when asid_cache(cpu) wraps to 0.
Date: Sun, 10 Jul 2016 13:04:47 +0000
Message-ID: <80B78A8B8FEE6145A87579E8435D78C30205D5F3@fzex.ruijie.com.cn> (raw)

From cd1eb951d4a7f01aaa24d2fb902f06b73ef4f608 Mon Sep 17 00:00:00 2001
From: yhb <yhb@ruijie.com.cn>
Date: Sun, 10 Jul 2016 20:43:05 +0800
Subject: [PATCH] MIPS: We need to clear MMU contexts of all other processes
 when asid_cache(cpu) wraps to 0.

Suppose that asid_cache(cpu) wraps to 0 every n days.
case 1:
(1)Process 1 got ASID 0x101.
(2)Process 1 slept for n days.
(3)asid_cache(cpu) wrapped to 0x101, and process 2 got ASID 0x101.
(4)Process 1 is woken,and ASID of process 1 is same as ASID of process 2.

case 2:
(1)Process 1 got ASID 0x101 on CPU 1.
(2)Process 1 migrated to CPU 2.
(3)Process 1 migrated to CPU 1 after n days.
(4)asid_cache on CPU 1 wrapped to 0x101, and process 2 got ASID 0x101.
(5)Process 1 is scheduled, and ASID of process 1 is same as ASID of process 2.

So we need to clear MMU contexts of all other processes when asid_cache(cpu) wraps to 0.

Signed-off-by: yhb <yhb@ruijie.com.cn>
---
 arch/blackfin/kernel/trace.c               |  7 ++--
 arch/frv/mm/mmu-context.c                  |  6 ++--
 arch/mips/include/asm/mmu_context.h        | 53 ++++++++++++++++++++++++++++--
 arch/um/kernel/reboot.c                    |  5 +--
 block/blk-cgroup.c                         |  6 ++--
 block/blk-ioc.c                            | 17 ++++++----
 drivers/staging/android/ion/ion.c          |  5 +--
 drivers/staging/android/lowmemorykiller.c  | 15 +++++----
 drivers/staging/lustre/lustre/ptlrpc/sec.c |  5 +--
 drivers/tty/tty_io.c                       |  6 ++--
 fs/coredump.c                              |  5 +--
 fs/exec.c                                  | 17 ++++++----
 fs/file.c                                  | 16 +++++----
 fs/fs_struct.c                             | 16 +++++----
 fs/hugetlbfs/inode.c                       |  6 ++--
 fs/namespace.c                             |  5 +--
 fs/proc/array.c                            |  5 +--
 fs/proc/base.c                             | 40 +++++++++++++---------
 fs/proc/internal.h                         |  5 +--
 fs/proc/proc_net.c                         |  6 ++--
 fs/proc/task_mmu.c                         |  5 +--
 fs/proc_namespace.c                        |  9 ++---
 include/linux/cpuset.h                     |  8 ++---
 include/linux/nsproxy.h                    |  6 ++--
 include/linux/oom.h                        |  3 +-
 include/linux/sched.h                      |  8 ++---
 ipc/namespace.c                            |  5 +--
 kernel/cgroup.c                            |  5 +--
 kernel/cpu.c                               |  5 +--
 kernel/cpuset.c                            |  7 ++--
 kernel/exit.c                              | 19 +++++++----
 kernel/fork.c                              | 32 +++++++++++-------
 kernel/kcmp.c                              |  5 +--
 kernel/nsproxy.c                           |  5 +--
 kernel/ptrace.c                            | 11 ++++---
 kernel/sched/debug.c                       |  5 +--
 kernel/sys.c                               | 16 +++++----
 kernel/utsname.c                           |  5 +--
 mm/memcontrol.c                            |  5 +--
 mm/mempolicy.c                             | 46 ++++++++++++++++----------
 mm/mmu_context.c                           | 10 +++---
 mm/oom_kill.c                              | 37 ++++++++++++---------
 net/core/net_namespace.c                   | 11 ++++---
 net/core/netclassid_cgroup.c               |  6 ++--
 net/core/netprio_cgroup.c                  |  5 +--
 45 files changed, 337 insertions(+), 188 deletions(-)

diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c
index 719dd79..a74843a 100644
--- a/arch/blackfin/kernel/trace.c
+++ b/arch/blackfin/kernel/trace.c
@@ -116,8 +116,9 @@ void decode_address(char *buf, unsigned long address)
 	read_lock(&tasklist_lock);
 	for_each_process(p) {
 		struct task_struct *t;
+		unsigned long irqflags;
 
-		t = find_lock_task_mm(p);
+		t = find_lock_task_mm(p, &irqflags);
 		if (!t)
 			continue;
 
@@ -165,7 +166,7 @@ void decode_address(char *buf, unsigned long address)
 						name, vma->vm_start, vma->vm_end);
 
 				up_read(&mm->mmap_sem);
-				task_unlock(t);
+				task_unlock(t, &irqflags);
 
 				if (buf[0] == '\0')
 					sprintf(buf, "[ %s ] dynamic memory", name);
@@ -176,7 +177,7 @@ void decode_address(char *buf, unsigned long address)
 
 		up_read(&mm->mmap_sem);
 __continue:
-		task_unlock(t);
+		task_unlock(t, &irqflags);
 	}
 
 	/*
diff --git a/arch/frv/mm/mmu-context.c b/arch/frv/mm/mmu-context.c
index 81757d5..dc525bd 100644
--- a/arch/frv/mm/mmu-context.c
+++ b/arch/frv/mm/mmu-context.c
@@ -183,15 +183,17 @@ int cxn_pin_by_pid(pid_t pid)
 	read_lock(&tasklist_lock);
 	tsk = find_task_by_vpid(pid);
 	if (tsk) {
+		unsigned long irqflags;
+
 		ret = -EINVAL;
 
-		task_lock(tsk);
+		task_lock(tsk, &irqflags);
 		if (tsk->mm) {
 			mm = tsk->mm;
 			atomic_inc(&mm->mm_users);
 			ret = 0;
 		}
-		task_unlock(tsk);
+		task_unlock(tsk, &irqflags);
 	}
 	read_unlock(&tasklist_lock);
 
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h
index 45914b5..68966b5 100644
--- a/arch/mips/include/asm/mmu_context.h
+++ b/arch/mips/include/asm/mmu_context.h
@@ -12,6 +12,7 @@
 #define _ASM_MMU_CONTEXT_H
 
 #include <linux/errno.h>
+#include <linux/oom.h>/* find_lock_task_mm */
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/slab.h>
@@ -97,6 +98,52 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 #define ASID_VERSION_MASK  ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
 #define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1)
 
+/*
+ * Yu Huabing
+ * Suppose that asid_cache(cpu) wraps to 0 every n days.
+ * case 1:
+ * (1)Process 1 got ASID 0x101.
+ * (2)Process 1 slept for n days.
+ * (3)asid_cache(cpu) wrapped to 0x101, and process 2 got ASID 0x101.
+ * (4)Process 1 is woken,and ASID of process 1 is same as ASID of process 2.
+ *
+ * case 2:
+ * (1)Process 1 got ASID 0x101 on CPU 1.
+ * (2)Process 1 migrated to CPU 2.
+ * (3)Process 1 migrated to CPU 1 after n days.
+ * (4)asid_cache on CPU 1 wrapped to 0x101, and process 2 got ASID 0x101.
+ * (5)Process 1 is scheduled,and ASID of process 1 is same as ASID of process 2.
+ *
+ * So we need to clear MMU contexts of all other processes when asid_cache(cpu)
+ * wraps to 0.
+ *
+ * This function might be called from hardirq context or process context.
+ */
+static inline void clear_other_mmu_contexts(struct mm_struct *mm,
+						unsigned long cpu)
+{
+	struct task_struct *p;
+	unsigned long irqflags;
+
+	read_lock(&tasklist_lock);
+	for_each_process(p) {
+		struct task_struct *t;
+
+		/*
+		 * Main thread might exit, but other threads may still have
+		 * a valid mm. Find one.
+		 */
+		t = find_lock_task_mm(p, &irqflags);
+		if (!t)
+			continue;
+
+		if (t->mm != mm)
+			cpu_context(cpu, t->mm) = 0;
+		task_unlock(t, &irqflags);
+	}
+	read_unlock(&tasklist_lock);
+}
+
 /* Normal, classic MIPS get_new_mmu_context */
 static inline void
 get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
@@ -112,8 +159,10 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
 #else
 		local_flush_tlb_all();	/* start new asid cycle */
 #endif
-		if (!asid)		/* fix version if needed */
-			asid = ASID_FIRST_VERSION;
+		if (!asid) {
+			asid = ASID_FIRST_VERSION; /* fix version if needed */
+			clear_other_mmu_contexts(mm, cpu);
+		}
 	}
 
 	cpu_context(cpu, mm) = asid_cache(cpu) = asid;
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index b60a9f8..452bd01 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -22,12 +22,13 @@ static void kill_off_processes(void)
 	read_lock(&tasklist_lock);
 	for_each_process(p) {
 		struct task_struct *t;
+		unsigned long irqflags;
 
-		t = find_lock_task_mm(p);
+		t = find_lock_task_mm(p, &irqflags);
 		if (!t)
 			continue;
 		pid = t->mm->context.id.u.pid;
-		task_unlock(t);
+		task_unlock(t, &irqflags);
 		os_kill_ptraced_process(pid, 1);
 	}
 	read_unlock(&tasklist_lock);
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 66e6f1a..3ffeb70 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -1145,11 +1145,13 @@ static int blkcg_can_attach(struct cgroup_taskset *tset)
 
 	/* task_lock() is needed to avoid races with exit_io_context() */
 	cgroup_taskset_for_each(task, dst_css, tset) {
-		task_lock(task);
+		unsigned long irqflags;
+
+		task_lock(task, &irqflags);
 		ioc = task->io_context;
 		if (ioc && atomic_read(&ioc->nr_tasks) > 1)
 			ret = -EINVAL;
-		task_unlock(task);
+		task_unlock(task, &irqflags);
 		if (ret)
 			break;
 	}
diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index 381cb50..4add102 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -200,11 +200,12 @@ retry:
 void exit_io_context(struct task_struct *task)
 {
 	struct io_context *ioc;
+	unsigned long irqflags;
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	ioc = task->io_context;
 	task->io_context = NULL;
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 
 	atomic_dec(&ioc->nr_tasks);
 	put_io_context_active(ioc);
@@ -235,6 +236,7 @@ int create_task_io_context(struct task_struct *task, gfp_t gfp_flags, int node)
 {
 	struct io_context *ioc;
 	int ret;
+	unsigned long irqflags;
 
 	ioc = kmem_cache_alloc_node(iocontext_cachep, gfp_flags | __GFP_ZERO,
 				    node);
@@ -257,7 +259,7 @@ int create_task_io_context(struct task_struct *task, gfp_t gfp_flags, int node)
 	 * path may issue IOs from e.g. exit_files().  The exit path is
 	 * responsible for not issuing IO after exit_io_context().
 	 */
-	task_lock(task);
+	task_lock(task, &irqflags);
 	if (!task->io_context &&
 	    (task == current || !(task->flags & PF_EXITING)))
 		task->io_context = ioc;
@@ -266,7 +268,7 @@ int create_task_io_context(struct task_struct *task, gfp_t gfp_flags, int node)
 
 	ret = task->io_context ? 0 : -EBUSY;
 
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 
 	return ret;
 }
@@ -288,18 +290,19 @@ struct io_context *get_task_io_context(struct task_struct *task,
 				       gfp_t gfp_flags, int node)
 {
 	struct io_context *ioc;
+	unsigned long irqflags;
 
 	might_sleep_if(gfpflags_allow_blocking(gfp_flags));
 
 	do {
-		task_lock(task);
+		task_lock(task, &irqflags);
 		ioc = task->io_context;
 		if (likely(ioc)) {
 			get_io_context(ioc);
-			task_unlock(task);
+			task_unlock(task, &irqflags);
 			return ioc;
 		}
-		task_unlock(task);
+		task_unlock(task, &irqflags);
 	} while (!create_task_io_context(task, gfp_flags, node));
 
 	return NULL;
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 8536567..7560f2f 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -806,6 +806,7 @@ struct ion_client *ion_client_create(struct ion_device *dev,
 	struct rb_node *parent = NULL;
 	struct ion_client *entry;
 	pid_t pid;
+	unsigned long irqflags;
 
 	if (!name) {
 		pr_err("%s: Name cannot be null\n", __func__);
@@ -813,7 +814,7 @@ struct ion_client *ion_client_create(struct ion_device *dev,
 	}
 
 	get_task_struct(current->group_leader);
-	task_lock(current->group_leader);
+	task_lock(current->group_leader, &irqflags);
 	pid = task_pid_nr(current->group_leader);
 	/*
 	 * don't bother to store task struct for kernel threads,
@@ -825,7 +826,7 @@ struct ion_client *ion_client_create(struct ion_device *dev,
 	} else {
 		task = current->group_leader;
 	}
-	task_unlock(current->group_leader);
+	task_unlock(current->group_leader, &irqflags);
 
 	client = kzalloc(sizeof(struct ion_client), GFP_KERNEL);
 	if (!client)
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 2509e5d..963aab9 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -123,27 +123,28 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
 	for_each_process(tsk) {
 		struct task_struct *p;
 		short oom_score_adj;
+		unsigned long irqflags;
 
 		if (tsk->flags & PF_KTHREAD)
 			continue;
 
-		p = find_lock_task_mm(tsk);
+		p = find_lock_task_mm(tsk, &irqflags);
 		if (!p)
 			continue;
 
 		if (test_tsk_thread_flag(p, TIF_MEMDIE) &&
 		    time_before_eq(jiffies, lowmem_deathpending_timeout)) {
-			task_unlock(p);
+			task_unlock(p, &irqflags);
 			rcu_read_unlock();
 			return 0;
 		}
 		oom_score_adj = p->signal->oom_score_adj;
 		if (oom_score_adj < min_score_adj) {
-			task_unlock(p);
+			task_unlock(p, &irqflags);
 			continue;
 		}
 		tasksize = get_mm_rss(p->mm);
-		task_unlock(p);
+		task_unlock(p, &irqflags);
 		if (tasksize <= 0)
 			continue;
 		if (selected) {
@@ -160,7 +161,9 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
 			     p->comm, p->pid, oom_score_adj, tasksize);
 	}
 	if (selected) {
-		task_lock(selected);
+		unsigned long irqflags;
+
+		task_lock(selected, &irqflags);
 		send_sig(SIGKILL, selected, 0);
 		/*
 		 * FIXME: lowmemorykiller shouldn't abuse global OOM killer
@@ -169,7 +172,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
 		 */
 		if (selected->mm)
 			mark_oom_victim(selected);
-		task_unlock(selected);
+		task_unlock(selected, &irqflags);
 		lowmem_print(1, "Killing '%s' (%d), adj %hd,\n"
 				 "   to free %ldkB on behalf of '%s' (%d) because\n"
 				 "   cache %ldkB is below limit %ldkB for oom_score_adj %hd\n"
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec.c b/drivers/staging/lustre/lustre/ptlrpc/sec.c
index 187fd1d..74549d3 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c
@@ -2193,6 +2193,7 @@ EXPORT_SYMBOL(sptlrpc_current_user_desc_size);
 int sptlrpc_pack_user_desc(struct lustre_msg *msg, int offset)
 {
 	struct ptlrpc_user_desc *pud;
+	unsigned long irqflags;
 
 	pud = lustre_msg_buf(msg, offset, 0);
 
@@ -2203,12 +2204,12 @@ int sptlrpc_pack_user_desc(struct lustre_msg *msg, int offset)
 	pud->pud_cap = cfs_curproc_cap_pack();
 	pud->pud_ngroups = (msg->lm_buflens[offset] - sizeof(*pud)) / 4;
 
-	task_lock(current);
+	task_lock(current, &irqflags);
 	if (pud->pud_ngroups > current_ngroups)
 		pud->pud_ngroups = current_ngroups;
 	memcpy(pud->pud_groups, current_cred()->group_info->blocks[0],
 	       pud->pud_ngroups * sizeof(__u32));
-	task_unlock(current);
+	task_unlock(current, &irqflags);
 
 	return 0;
 }
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 24d5491..d10475b 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3085,20 +3085,22 @@ void __do_SAK(struct tty_struct *tty)
 
 	/* Now kill any processes that happen to have the tty open */
 	do_each_thread(g, p) {
+		unsigned long irqflags;
+
 		if (p->signal->tty == tty) {
 			tty_notice(tty, "SAK: killed process %d (%s): by controlling tty\n",
 				   task_pid_nr(p), p->comm);
 			send_sig(SIGKILL, p, 1);
 			continue;
 		}
-		task_lock(p);
+		task_lock(p, &irqflags);
 		i = iterate_fd(p->files, 0, this_tty, tty);
 		if (i != 0) {
 			tty_notice(tty, "SAK: killed process %d (%s): by fd#%d\n",
 				   task_pid_nr(p), p->comm, i - 1);
 			force_sig(SIGKILL, p);
 		}
-		task_unlock(p);
+		task_unlock(p, &irqflags);
 	} while_each_thread(g, p);
 	read_unlock(&tasklist_lock);
 #endif
diff --git a/fs/coredump.c b/fs/coredump.c
index 47c32c3..5122e6f 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -703,10 +703,11 @@ void do_coredump(const siginfo_t *siginfo)
 			 * root directory of init_task.
 			 */
 			struct path root;
+			unsigned long irqflags;
 
-			task_lock(&init_task);
+			task_lock(&init_task, &irqflags);
 			get_fs_root(init_task.fs, &root);
-			task_unlock(&init_task);
+			task_unlock(&init_task, &irqflags);
 			cprm.file = file_open_root(root.dentry, root.mnt,
 				cn.corename, open_flags, 0600);
 			path_put(&root);
diff --git a/fs/exec.c b/fs/exec.c
index c4010b8..7e95215 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -940,6 +940,7 @@ static int exec_mmap(struct mm_struct *mm)
 {
 	struct task_struct *tsk;
 	struct mm_struct *old_mm, *active_mm;
+	unsigned long irqflags;
 
 	/* Notify parent that we're no longer interested in the old VM */
 	tsk = current;
@@ -960,14 +961,14 @@ static int exec_mmap(struct mm_struct *mm)
 			return -EINTR;
 		}
 	}
-	task_lock(tsk);
+	task_lock(tsk, &irqflags);
 	active_mm = tsk->active_mm;
 	tsk->mm = mm;
 	tsk->active_mm = mm;
 	activate_mm(active_mm, mm);
 	tsk->mm->vmacache_seqnum = 0;
 	vmacache_flush(tsk);
-	task_unlock(tsk);
+	task_unlock(tsk, &irqflags);
 	if (old_mm) {
 		up_read(&old_mm->mmap_sem);
 		BUG_ON(active_mm != old_mm);
@@ -1153,10 +1154,12 @@ killed:
 
 char *get_task_comm(char *buf, struct task_struct *tsk)
 {
+	unsigned long irqflags;
+
 	/* buf must be at least sizeof(tsk->comm) in size */
-	task_lock(tsk);
+	task_lock(tsk, &irqflags);
 	strncpy(buf, tsk->comm, sizeof(tsk->comm));
-	task_unlock(tsk);
+	task_unlock(tsk, &irqflags);
 	return buf;
 }
 EXPORT_SYMBOL_GPL(get_task_comm);
@@ -1168,10 +1171,12 @@ EXPORT_SYMBOL_GPL(get_task_comm);
 
 void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec)
 {
-	task_lock(tsk);
+	unsigned long irqflags;
+
+	task_lock(tsk, &irqflags);
 	trace_task_rename(tsk, buf);
 	strlcpy(tsk->comm, buf, sizeof(tsk->comm));
-	task_unlock(tsk);
+	task_unlock(tsk, &irqflags);
 	perf_event_comm(tsk, exec);
 }
 
diff --git a/fs/file.c b/fs/file.c
index 1fbc5c0..19cbf9b 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -418,12 +418,13 @@ static struct fdtable *close_files(struct files_struct * files)
 struct files_struct *get_files_struct(struct task_struct *task)
 {
 	struct files_struct *files;
+	unsigned long irqflags;
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	files = task->files;
 	if (files)
 		atomic_inc(&files->count);
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 
 	return files;
 }
@@ -444,11 +445,12 @@ void reset_files_struct(struct files_struct *files)
 {
 	struct task_struct *tsk = current;
 	struct files_struct *old;
+	unsigned long irqflags;
 
 	old = tsk->files;
-	task_lock(tsk);
+	task_lock(tsk, &irqflags);
 	tsk->files = files;
-	task_unlock(tsk);
+	task_unlock(tsk, &irqflags);
 	put_files_struct(old);
 }
 
@@ -457,9 +459,11 @@ void exit_files(struct task_struct *tsk)
 	struct files_struct * files = tsk->files;
 
 	if (files) {
-		task_lock(tsk);
+		unsigned long irqflags;
+
+		task_lock(tsk, &irqflags);
 		tsk->files = NULL;
-		task_unlock(tsk);
+		task_unlock(tsk, &irqflags);
 		put_files_struct(files);
 	}
 }
diff --git a/fs/fs_struct.c b/fs/fs_struct.c
index 7dca743..426dab4 100644
--- a/fs/fs_struct.c
+++ b/fs/fs_struct.c
@@ -58,10 +58,11 @@ void chroot_fs_refs(const struct path *old_root, const struct path *new_root)
 	struct task_struct *g, *p;
 	struct fs_struct *fs;
 	int count = 0;
+	unsigned long irqflags;
 
 	read_lock(&tasklist_lock);
 	do_each_thread(g, p) {
-		task_lock(p);
+		task_lock(p, &irqflags);
 		fs = p->fs;
 		if (fs) {
 			int hits = 0;
@@ -76,7 +77,7 @@ void chroot_fs_refs(const struct path *old_root, const struct path *new_root)
 			}
 			spin_unlock(&fs->lock);
 		}
-		task_unlock(p);
+		task_unlock(p, &irqflags);
 	} while_each_thread(g, p);
 	read_unlock(&tasklist_lock);
 	while (count--)
@@ -95,13 +96,15 @@ void exit_fs(struct task_struct *tsk)
 	struct fs_struct *fs = tsk->fs;
 
 	if (fs) {
+		unsigned long irqflags;
 		int kill;
-		task_lock(tsk);
+
+		task_lock(tsk, &irqflags);
 		spin_lock(&fs->lock);
 		tsk->fs = NULL;
 		kill = !--fs->users;
 		spin_unlock(&fs->lock);
-		task_unlock(tsk);
+		task_unlock(tsk, &irqflags);
 		if (kill)
 			free_fs_struct(fs);
 	}
@@ -133,16 +136,17 @@ int unshare_fs_struct(void)
 	struct fs_struct *fs = current->fs;
 	struct fs_struct *new_fs = copy_fs_struct(fs);
 	int kill;
+	unsigned long irqflags;
 
 	if (!new_fs)
 		return -ENOMEM;
 
-	task_lock(current);
+	task_lock(current, &irqflags);
 	spin_lock(&fs->lock);
 	kill = !--fs->users;
 	current->fs = new_fs;
 	spin_unlock(&fs->lock);
-	task_unlock(current);
+	task_unlock(current, &irqflags);
 
 	if (kill)
 		free_fs_struct(fs);
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 4ea71eb..73e7591 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -1260,10 +1260,12 @@ struct file *hugetlb_file_setup(const char *name, size_t size,
 	if (creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm()) {
 		*user = current_user();
 		if (user_shm_lock(size, *user)) {
-			task_lock(current);
+			unsigned long irqflags;
+
+			task_lock(current, &irqflags);
 			pr_warn_once("%s (%d): Using mlock ulimits for SHM_HUGETLB is deprecated\n",
 				current->comm, current->pid);
-			task_unlock(current);
+			task_unlock(current, &irqflags);
 		} else {
 			*user = NULL;
 			return ERR_PTR(-EPERM);
diff --git a/fs/namespace.c b/fs/namespace.c
index 4fb1691..504408d 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3294,16 +3294,17 @@ found:
 
 static struct ns_common *mntns_get(struct task_struct *task)
 {
+	unsigned long irqflags;
 	struct ns_common *ns = NULL;
 	struct nsproxy *nsproxy;
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	nsproxy = task->nsproxy;
 	if (nsproxy) {
 		ns = &nsproxy->mnt_ns->ns;
 		get_mnt_ns(to_mnt_ns(ns));
 	}
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 
 	return ns;
 }
diff --git a/fs/proc/array.c b/fs/proc/array.c
index b6c00ce..07907e7 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -149,6 +149,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
 	const struct cred *cred;
 	pid_t ppid, tpid = 0, tgid, ngid;
 	unsigned int max_fds = 0;
+	unsigned long irqflags;
 
 	rcu_read_lock();
 	ppid = pid_alive(p) ?
@@ -162,10 +163,10 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
 	ngid = task_numa_group_id(p);
 	cred = get_task_cred(p);
 
-	task_lock(p);
+	task_lock(p, &irqflags);
 	if (p->files)
 		max_fds = files_fdtable(p->files)->max_fds;
-	task_unlock(p);
+	task_unlock(p, &irqflags);
 	rcu_read_unlock();
 
 	seq_printf(m,
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 0d163a8..eef7d4d 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -157,13 +157,14 @@ static unsigned int pid_entry_count_dirs(const struct pid_entry *entries,
 static int get_task_root(struct task_struct *task, struct path *root)
 {
 	int result = -ENOENT;
+	unsigned long irqflags;
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	if (task->fs) {
 		get_fs_root(task->fs, root);
 		result = 0;
 	}
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 	return result;
 }
 
@@ -173,12 +174,14 @@ static int proc_cwd_link(struct dentry *dentry, struct path *path)
 	int result = -ENOENT;
 
 	if (task) {
-		task_lock(task);
+		unsigned long irqflags;
+
+		task_lock(task, &irqflags);
 		if (task->fs) {
 			get_fs_pwd(task->fs, path);
 			result = 0;
 		}
-		task_unlock(task);
+		task_unlock(task, &irqflags);
 		put_task_struct(task);
 	}
 	return result;
@@ -1057,7 +1060,7 @@ static ssize_t oom_adj_write(struct file *file, const char __user *buf,
 	struct task_struct *task;
 	char buffer[PROC_NUMBUF];
 	int oom_adj;
-	unsigned long flags;
+	unsigned long flags, irqflags;
 	int err;
 
 	memset(buffer, 0, sizeof(buffer));
@@ -1083,7 +1086,7 @@ static ssize_t oom_adj_write(struct file *file, const char __user *buf,
 		goto out;
 	}
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	if (!task->mm) {
 		err = -EINVAL;
 		goto err_task_lock;
@@ -1122,7 +1125,7 @@ static ssize_t oom_adj_write(struct file *file, const char __user *buf,
 err_sighand:
 	unlock_task_sighand(task, &flags);
 err_task_lock:
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 	put_task_struct(task);
 out:
 	return err < 0 ? err : count;
@@ -1159,7 +1162,7 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf,
 {
 	struct task_struct *task;
 	char buffer[PROC_NUMBUF];
-	unsigned long flags;
+	unsigned long flags, irqflags;
 	int oom_score_adj;
 	int err;
 
@@ -1186,7 +1189,7 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf,
 		goto out;
 	}
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	if (!task->mm) {
 		err = -EINVAL;
 		goto err_task_lock;
@@ -1211,7 +1214,7 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf,
 err_sighand:
 	unlock_task_sighand(task, &flags);
 err_task_lock:
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 	put_task_struct(task);
 out:
 	return err < 0 ? err : count;
@@ -1522,14 +1525,15 @@ static int comm_show(struct seq_file *m, void *v)
 {
 	struct inode *inode = m->private;
 	struct task_struct *p;
+	unsigned long irqflags;
 
 	p = get_proc_task(inode);
 	if (!p)
 		return -ESRCH;
 
-	task_lock(p);
+	task_lock(p, &irqflags);
 	seq_printf(m, "%s\n", p->comm);
-	task_unlock(p);
+	task_unlock(p, &irqflags);
 
 	put_task_struct(p);
 
@@ -2277,12 +2281,14 @@ static ssize_t timerslack_ns_write(struct file *file, const char __user *buf,
 		return -ESRCH;
 
 	if (ptrace_may_access(p, PTRACE_MODE_ATTACH_FSCREDS)) {
-		task_lock(p);
+		unsigned long irqflags;
+
+		task_lock(p, &irqflags);
 		if (slack_ns == 0)
 			p->timer_slack_ns = p->default_timer_slack_ns;
 		else
 			p->timer_slack_ns = slack_ns;
-		task_unlock(p);
+		task_unlock(p, &irqflags);
 	} else
 		count = -EPERM;
 
@@ -2302,9 +2308,11 @@ static int timerslack_ns_show(struct seq_file *m, void *v)
 		return -ESRCH;
 
 	if (ptrace_may_access(p, PTRACE_MODE_ATTACH_FSCREDS)) {
-		task_lock(p);
+		unsigned long irqflags;
+
+		task_lock(p, &irqflags);
 		seq_printf(m, "%llu\n", p->timer_slack_ns);
-		task_unlock(p);
+		task_unlock(p, &irqflags);
 	} else
 		err = -EPERM;
 
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index aa27810..33da171 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -99,14 +99,15 @@ static inline struct task_struct *get_proc_task(struct inode *inode)
 
 static inline int task_dumpable(struct task_struct *task)
 {
+	unsigned long irqflags;
 	int dumpable = 0;
 	struct mm_struct *mm;
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	mm = task->mm;
 	if (mm)
 		dumpable = get_dumpable(mm);
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 	if (dumpable == SUID_DUMP_USER)
 		return 1;
 	return 0;
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
index 350984a..ffb8c8f 100644
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -113,11 +113,13 @@ static struct net *get_proc_task_net(struct inode *dir)
 	rcu_read_lock();
 	task = pid_task(proc_pid(dir), PIDTYPE_PID);
 	if (task != NULL) {
-		task_lock(task);
+		unsigned long irqflags;
+
+		task_lock(task, &irqflags);
 		ns = task->nsproxy;
 		if (ns != NULL)
 			net = get_net(ns->net_ns);
-		task_unlock(task);
+		task_unlock(task, &irqflags);
 	}
 	rcu_read_unlock();
 
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 5415835..f86f3bb 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -107,12 +107,13 @@ unsigned long task_statm(struct mm_struct *mm,
  */
 static void hold_task_mempolicy(struct proc_maps_private *priv)
 {
+	unsigned long irqflags;
 	struct task_struct *task = priv->task;
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	priv->task_mempolicy = get_task_policy(task);
 	mpol_get(priv->task_mempolicy);
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 }
 static void release_task_mempolicy(struct proc_maps_private *priv)
 {
diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c
index 3f1190d..a3cc5cb 100644
--- a/fs/proc_namespace.c
+++ b/fs/proc_namespace.c
@@ -242,27 +242,28 @@ static int mounts_open_common(struct inode *inode, struct file *file,
 	struct proc_mounts *p;
 	struct seq_file *m;
 	int ret = -EINVAL;
+	unsigned long irqflags;
 
 	if (!task)
 		goto err;
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	nsp = task->nsproxy;
 	if (!nsp || !nsp->mnt_ns) {
-		task_unlock(task);
+		task_unlock(task, &irqflags);
 		put_task_struct(task);
 		goto err;
 	}
 	ns = nsp->mnt_ns;
 	get_mnt_ns(ns);
 	if (!task->fs) {
-		task_unlock(task);
+		task_unlock(task, &irqflags);
 		put_task_struct(task);
 		ret = -ENOENT;
 		goto err_put_ns;
 	}
 	get_fs_root(task->fs, &root);
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 	put_task_struct(task);
 
 	ret = seq_open_private(file, &mounts_op, sizeof(struct proc_mounts));
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 85a868c..ed091ba 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -126,15 +126,13 @@ static inline bool read_mems_allowed_retry(unsigned int seq)
 
 static inline void set_mems_allowed(nodemask_t nodemask)
 {
-	unsigned long flags;
+	unsigned long irqflags;
 
-	task_lock(current);
-	local_irq_save(flags);
+	task_lock(current, &irqflags);
 	write_seqcount_begin(&current->mems_allowed_seq);
 	current->mems_allowed = nodemask;
 	write_seqcount_end(&current->mems_allowed_seq);
-	local_irq_restore(flags);
-	task_unlock(current);
+	task_unlock(current, &irqflags);
 }
 
 #else /* !CONFIG_CPUSETS */
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index ac0d65b..32b80dc 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -49,7 +49,9 @@ extern struct nsproxy init_nsproxy;
  *     precautions should be taken - just dereference the pointers
  *
  *  3. the access to other task namespaces is performed like this
- *     task_lock(task);
+ *     unsigned long irqflags;
+ *
+ *     task_lock(task, &irqflags);
  *     nsproxy = task->nsproxy;
  *     if (nsproxy != NULL) {
  *             / *
@@ -60,7 +62,7 @@ extern struct nsproxy init_nsproxy;
  *         * NULL task->nsproxy means that this task is
  *         * almost dead (zombie)
  *         * /
- *     task_unlock(task);
+ *     task_unlock(task, &irqflags);
  *
  */
 
diff --git a/include/linux/oom.h b/include/linux/oom.h
index 628a432..80251a8 100644
--- a/include/linux/oom.h
+++ b/include/linux/oom.h
@@ -98,7 +98,8 @@ extern bool oom_killer_disabled;
 extern bool oom_killer_disable(void);
 extern void oom_killer_enable(void);
 
-extern struct task_struct *find_lock_task_mm(struct task_struct *p);
+extern struct task_struct *find_lock_task_mm(struct task_struct *p,
+								unsigned long *irqflags);
 
 static inline bool task_will_free_mem(struct task_struct *task)
 {
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 52c4847..9e643fd 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2769,14 +2769,14 @@ static inline int thread_group_empty(struct task_struct *p)
  * It must not be nested with write_lock_irq(&tasklist_lock),
  * neither inside nor outside.
  */
-static inline void task_lock(struct task_struct *p)
+static inline void task_lock(struct task_struct *p, unsigned long *irqflags)
 {
-	spin_lock(&p->alloc_lock);
+	spin_lock_irqsave(&p->alloc_lock, *irqflags);
 }
 
-static inline void task_unlock(struct task_struct *p)
+static inline void task_unlock(struct task_struct *p, unsigned long *irqflags)
 {
-	spin_unlock(&p->alloc_lock);
+	spin_unlock_irqrestore(&p->alloc_lock, *irqflags);
 }
 
 extern struct sighand_struct *__lock_task_sighand(struct task_struct *tsk,
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 068caf1..4994299 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -135,14 +135,15 @@ static inline struct ipc_namespace *to_ipc_ns(struct ns_common *ns)
 
 static struct ns_common *ipcns_get(struct task_struct *task)
 {
+	unsigned long irqflags;
 	struct ipc_namespace *ns = NULL;
 	struct nsproxy *nsproxy;
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	nsproxy = task->nsproxy;
 	if (nsproxy)
 		ns = get_ipc_ns(nsproxy->ipc_ns);
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 
 	return ns ? &ns->ns : NULL;
 }
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 86cb5c6..693b474 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -6354,14 +6354,15 @@ static struct ns_common *cgroupns_get(struct task_struct *task)
 {
 	struct cgroup_namespace *ns = NULL;
 	struct nsproxy *nsproxy;
+	unsigned long irqflags;
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	nsproxy = task->nsproxy;
 	if (nsproxy) {
 		ns = nsproxy->cgroup_ns;
 		get_cgroup_ns(ns);
 	}
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 
 	return ns ? &ns->ns : NULL;
 }
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 3e3f6e4..0109299 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -615,16 +615,17 @@ void clear_tasks_mm_cpumask(int cpu)
 	rcu_read_lock();
 	for_each_process(p) {
 		struct task_struct *t;
+		unsigned long irqflags;
 
 		/*
 		 * Main thread might exit, but other threads may still have
 		 * a valid mm. Find one.
 		 */
-		t = find_lock_task_mm(p);
+		t = find_lock_task_mm(p, &irqflags);
 		if (!t)
 			continue;
 		cpumask_clear_cpu(cpu, mm_cpumask(t->mm));
-		task_unlock(t);
+		task_unlock(t, &irqflags);
 	}
 	rcu_read_unlock();
 }
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 1902956b..8bd56cc 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -1033,6 +1033,7 @@ static void cpuset_change_task_nodemask(struct task_struct *tsk,
 					nodemask_t *newmems)
 {
 	bool need_loop;
+	unsigned long irqflags;
 
 	/*
 	 * Allow tasks that have access to memory reserves because they have
@@ -1043,7 +1044,7 @@ static void cpuset_change_task_nodemask(struct task_struct *tsk,
 	if (current->flags & PF_EXITING) /* Let dying task have memory */
 		return;
 
-	task_lock(tsk);
+	task_lock(tsk, &irqflags);
 	/*
 	 * Determine if a loop is necessary if another thread is doing
 	 * read_mems_allowed_begin().  If at least one node remains unchanged and
@@ -1054,7 +1055,6 @@ static void cpuset_change_task_nodemask(struct task_struct *tsk,
 			!nodes_intersects(*newmems, tsk->mems_allowed);
 
 	if (need_loop) {
-		local_irq_disable();
 		write_seqcount_begin(&tsk->mems_allowed_seq);
 	}
 
@@ -1066,10 +1066,9 @@ static void cpuset_change_task_nodemask(struct task_struct *tsk,
 
 	if (need_loop) {
 		write_seqcount_end(&tsk->mems_allowed_seq);
-		local_irq_enable();
 	}
 
-	task_unlock(tsk);
+	task_unlock(tsk, &irqflags);
 }
 
 static void *cpuset_being_rebound;
diff --git a/kernel/exit.c b/kernel/exit.c
index 79c7e38..a4de5ed 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -298,6 +298,7 @@ kill_orphaned_pgrp(struct task_struct *tsk, struct task_struct *parent)
 void mm_update_next_owner(struct mm_struct *mm)
 {
 	struct task_struct *c, *g, *p = current;
+	unsigned long irqflags;
 
 retry:
 	/*
@@ -362,19 +363,19 @@ assign_new_owner:
 	 * The task_lock protects c->mm from changing.
 	 * We always want mm->owner->mm == mm
 	 */
-	task_lock(c);
+	task_lock(c, &irqflags);
 	/*
 	 * Delay read_unlock() till we have the task_lock()
 	 * to ensure that c does not slip away underneath us
 	 */
 	read_unlock(&tasklist_lock);
 	if (c->mm != mm) {
-		task_unlock(c);
+		task_unlock(c, &irqflags);
 		put_task_struct(c);
 		goto retry;
 	}
 	mm->owner = c;
-	task_unlock(c);
+	task_unlock(c, &irqflags);
 	put_task_struct(c);
 }
 #endif /* CONFIG_MEMCG */
@@ -387,6 +388,7 @@ static void exit_mm(struct task_struct *tsk)
 {
 	struct mm_struct *mm = tsk->mm;
 	struct core_state *core_state;
+	unsigned long irqflags;
 
 	mm_release(tsk, mm);
 	if (!mm)
@@ -427,11 +429,11 @@ static void exit_mm(struct task_struct *tsk)
 	atomic_inc(&mm->mm_count);
 	BUG_ON(mm != tsk->active_mm);
 	/* more a memory barrier than a real lock */
-	task_lock(tsk);
+	task_lock(tsk, &irqflags);
 	tsk->mm = NULL;
 	up_read(&mm->mmap_sem);
 	enter_lazy_tlb(mm, current);
-	task_unlock(tsk);
+	task_unlock(tsk, &irqflags);
 	mm_update_next_owner(mm);
 	mmput(mm);
 	if (test_thread_flag(TIF_MEMDIE))
@@ -654,6 +656,9 @@ void do_exit(long code)
 	struct task_struct *tsk = current;
 	int group_dead;
 	TASKS_RCU(int tasks_rcu_i);
+#ifdef CONFIG_NUMA
+	unsigned long irqflags;
+#endif
 
 	profile_task_exit(tsk);
 	kcov_task_exit(tsk);
@@ -769,10 +774,10 @@ void do_exit(long code)
 	exit_notify(tsk, group_dead);
 	proc_exit_connector(tsk);
 #ifdef CONFIG_NUMA
-	task_lock(tsk);
+	task_lock(tsk, &irqflags);
 	mpol_put(tsk->mempolicy);
 	tsk->mempolicy = NULL;
-	task_unlock(tsk);
+	task_unlock(tsk, &irqflags);
 #endif
 #ifdef CONFIG_FUTEX
 	if (unlikely(current->pi_state_cache))
diff --git a/kernel/fork.c b/kernel/fork.c
index d277e83..388ba3f 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -785,8 +785,9 @@ EXPORT_SYMBOL(get_mm_exe_file);
 struct mm_struct *get_task_mm(struct task_struct *task)
 {
 	struct mm_struct *mm;
+	unsigned long irqflags;
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	mm = task->mm;
 	if (mm) {
 		if (task->flags & PF_KTHREAD)
@@ -794,7 +795,7 @@ struct mm_struct *get_task_mm(struct task_struct *task)
 		else
 			atomic_inc(&mm->mm_users);
 	}
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 	return mm;
 }
 EXPORT_SYMBOL_GPL(get_task_mm);
@@ -822,14 +823,15 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
 static void complete_vfork_done(struct task_struct *tsk)
 {
 	struct completion *vfork;
+	unsigned long irqflags;
 
-	task_lock(tsk);
+	task_lock(tsk, &irqflags);
 	vfork = tsk->vfork_done;
 	if (likely(vfork)) {
 		tsk->vfork_done = NULL;
 		complete(vfork);
 	}
-	task_unlock(tsk);
+	task_unlock(tsk, &irqflags);
 }
 
 static int wait_for_vfork_done(struct task_struct *child,
@@ -842,9 +844,11 @@ static int wait_for_vfork_done(struct task_struct *child,
 	freezer_count();
 
 	if (killed) {
-		task_lock(child);
+		unsigned long irqflags;
+
+		task_lock(child, &irqflags);
 		child->vfork_done = NULL;
-		task_unlock(child);
+		task_unlock(child, &irqflags);
 	}
 
 	put_task_struct(child);
@@ -1126,6 +1130,7 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)
 static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
 {
 	struct signal_struct *sig;
+	unsigned long irqflags;
 
 	if (clone_flags & CLONE_THREAD)
 		return 0;
@@ -1153,9 +1158,9 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
 	hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 	sig->real_timer.function = it_real_fn;
 
-	task_lock(current->group_leader);
+	task_lock(current->group_leader, &irqflags);
 	memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
-	task_unlock(current->group_leader);
+	task_unlock(current->group_leader, &irqflags);
 
 	posix_cpu_timers_init_group(sig);
 
@@ -2022,6 +2027,8 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
 		goto bad_unshare_cleanup_cred;
 
 	if (new_fs || new_fd || do_sysvsem || new_cred || new_nsproxy) {
+		unsigned long irqflags;
+
 		if (do_sysvsem) {
 			/*
 			 * CLONE_SYSVSEM is equivalent to sys_exit().
@@ -2037,7 +2044,7 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
 		if (new_nsproxy)
 			switch_task_namespaces(current, new_nsproxy);
 
-		task_lock(current);
+		task_lock(current, &irqflags);
 
 		if (new_fs) {
 			fs = current->fs;
@@ -2056,7 +2063,7 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
 			new_fd = fd;
 		}
 
-		task_unlock(current);
+		task_unlock(current, &irqflags);
 
 		if (new_cred) {
 			/* Install the new user namespace */
@@ -2091,6 +2098,7 @@ int unshare_files(struct files_struct **displaced)
 	struct task_struct *task = current;
 	struct files_struct *copy = NULL;
 	int error;
+	unsigned long irqflags;
 
 	error = unshare_fd(CLONE_FILES, &copy);
 	if (error || !copy) {
@@ -2098,9 +2106,9 @@ int unshare_files(struct files_struct **displaced)
 		return error;
 	}
 	*displaced = task->files;
-	task_lock(task);
+	task_lock(task, &irqflags);
 	task->files = copy;
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 	return 0;
 }
 
diff --git a/kernel/kcmp.c b/kernel/kcmp.c
index 3a47fa9..e5b5412 100644
--- a/kernel/kcmp.c
+++ b/kernel/kcmp.c
@@ -57,15 +57,16 @@ static struct file *
 get_file_raw_ptr(struct task_struct *task, unsigned int idx)
 {
 	struct file *file = NULL;
+	unsigned long irqflags;
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	rcu_read_lock();
 
 	if (task->files)
 		file = fcheck_files(task->files, idx);
 
 	rcu_read_unlock();
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 
 	return file;
 }
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index 782102e..65f407d 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -216,13 +216,14 @@ out:
 void switch_task_namespaces(struct task_struct *p, struct nsproxy *new)
 {
 	struct nsproxy *ns;
+	unsigned long irqflags;
 
 	might_sleep();
 
-	task_lock(p);
+	task_lock(p, &irqflags);
 	ns = p->nsproxy;
 	p->nsproxy = new;
-	task_unlock(p);
+	task_unlock(p, &irqflags);
 
 	if (ns && atomic_dec_and_test(&ns->count))
 		free_nsproxy(ns);
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index d49bfa1..2aba142 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -286,9 +286,11 @@ ok:
 bool ptrace_may_access(struct task_struct *task, unsigned int mode)
 {
 	int err;
-	task_lock(task);
+	unsigned long irqflags;
+
+	task_lock(task, &irqflags);
 	err = __ptrace_may_access(task, mode);
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 	return !err;
 }
 
@@ -298,6 +300,7 @@ static int ptrace_attach(struct task_struct *task, long request,
 {
 	bool seize = (request == PTRACE_SEIZE);
 	int retval;
+	unsigned long irqflags;
 
 	retval = -EIO;
 	if (seize) {
@@ -327,9 +330,9 @@ static int ptrace_attach(struct task_struct *task, long request,
 	if (mutex_lock_interruptible(&task->signal->cred_guard_mutex))
 		goto out;
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH_REALCREDS);
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 	if (retval)
 		goto unlock_creds;
 
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 4fbc3bd..a95f445 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -841,16 +841,17 @@ static void sched_show_numa(struct task_struct *p, struct seq_file *m)
 {
 #ifdef CONFIG_NUMA_BALANCING
 	struct mempolicy *pol;
+	unsigned long irqflags;
 
 	if (p->mm)
 		P(mm->numa_scan_seq);
 
-	task_lock(p);
+	task_lock(p, &irqflags);
 	pol = p->mempolicy;
 	if (pol && !(pol->flags & MPOL_F_MORON))
 		pol = NULL;
 	mpol_get(pol);
-	task_unlock(p);
+	task_unlock(p, &irqflags);
 
 	P(numa_pages_migrated);
 	P(numa_preferred_nid);
diff --git a/kernel/sys.c b/kernel/sys.c
index cf8ba54..fb2e6a8 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1308,12 +1308,14 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
 		struct rlimit __user *, rlim)
 {
 	struct rlimit x;
+	unsigned long irqflags;
+
 	if (resource >= RLIM_NLIMITS)
 		return -EINVAL;
 
-	task_lock(current->group_leader);
+	task_lock(current->group_leader, &irqflags);
 	x = current->signal->rlim[resource];
-	task_unlock(current->group_leader);
+	task_unlock(current->group_leader, &irqflags);
 	if (x.rlim_cur > 0x7FFFFFFF)
 		x.rlim_cur = 0x7FFFFFFF;
 	if (x.rlim_max > 0x7FFFFFFF)
@@ -1362,6 +1364,7 @@ int do_prlimit(struct task_struct *tsk, unsigned int resource,
 {
 	struct rlimit *rlim;
 	int retval = 0;
+	unsigned long irqflags;
 
 	if (resource >= RLIM_NLIMITS)
 		return -EINVAL;
@@ -1381,7 +1384,7 @@ int do_prlimit(struct task_struct *tsk, unsigned int resource,
 	}
 
 	rlim = tsk->signal->rlim + resource;
-	task_lock(tsk->group_leader);
+	task_lock(tsk->group_leader, &irqflags);
 	if (new_rlim) {
 		/* Keep the capable check against init_user_ns until
 		   cgroups can contain all limits */
@@ -1407,7 +1410,7 @@ int do_prlimit(struct task_struct *tsk, unsigned int resource,
 		if (new_rlim)
 			*rlim = *new_rlim;
 	}
-	task_unlock(tsk->group_leader);
+	task_unlock(tsk->group_leader, &irqflags);
 
 	/*
 	 * RLIMIT_CPU handling.   Note that the kernel fails to return an error
@@ -1911,6 +1914,7 @@ static int prctl_set_auxv(struct mm_struct *mm, unsigned long addr,
 	 * tools which use this vector might be unhappy.
 	 */
 	unsigned long user_auxv[AT_VECTOR_SIZE];
+	unsigned long irqflags;
 
 	if (len > sizeof(user_auxv))
 		return -EINVAL;
@@ -1924,9 +1928,9 @@ static int prctl_set_auxv(struct mm_struct *mm, unsigned long addr,
 
 	BUILD_BUG_ON(sizeof(user_auxv) != sizeof(mm->saved_auxv));
 
-	task_lock(current);
+	task_lock(current, &irqflags);
 	memcpy(mm->saved_auxv, user_auxv, len);
-	task_unlock(current);
+	task_unlock(current, &irqflags);
 
 	return 0;
 }
diff --git a/kernel/utsname.c b/kernel/utsname.c
index 831ea71..5732717 100644
--- a/kernel/utsname.c
+++ b/kernel/utsname.c
@@ -99,14 +99,15 @@ static struct ns_common *utsns_get(struct task_struct *task)
 {
 	struct uts_namespace *ns = NULL;
 	struct nsproxy *nsproxy;
+	unsigned long irqflags;
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	nsproxy = task->nsproxy;
 	if (nsproxy) {
 		ns = nsproxy->uts_ns;
 		get_uts_ns(ns);
 	}
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 
 	return ns ? &ns->ns : NULL;
 }
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index a2e79b8..21d50f0 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1046,11 +1046,12 @@ bool task_in_mem_cgroup(struct task_struct *task, struct mem_cgroup *memcg)
 	struct mem_cgroup *task_memcg;
 	struct task_struct *p;
 	bool ret;
+	unsigned long irqflags;
 
-	p = find_lock_task_mm(task);
+	p = find_lock_task_mm(task, &irqflags);
 	if (p) {
 		task_memcg = get_mem_cgroup_from_mm(p->mm);
-		task_unlock(p);
+		task_unlock(p, &irqflags);
 	} else {
 		/*
 		 * All threads may have already detached their mm's, but the oom
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 36cc01b..05abb22 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -789,6 +789,7 @@ static long do_set_mempolicy(unsigned short mode, unsigned short flags,
 	struct mempolicy *new, *old;
 	NODEMASK_SCRATCH(scratch);
 	int ret;
+	unsigned long irqflags;
 
 	if (!scratch)
 		return -ENOMEM;
@@ -799,10 +800,10 @@ static long do_set_mempolicy(unsigned short mode, unsigned short flags,
 		goto out;
 	}
 
-	task_lock(current);
+	task_lock(current, &irqflags);
 	ret = mpol_set_nodemask(new, nodes, scratch);
 	if (ret) {
-		task_unlock(current);
+		task_unlock(current, &irqflags);
 		mpol_put(new);
 		goto out;
 	}
@@ -811,7 +812,7 @@ static long do_set_mempolicy(unsigned short mode, unsigned short flags,
 	if (new && new->mode == MPOL_INTERLEAVE &&
 	    nodes_weight(new->v.nodes))
 		current->il_next = first_node(new->v.nodes);
-	task_unlock(current);
+	task_unlock(current, &irqflags);
 	mpol_put(old);
 	ret = 0;
 out:
@@ -873,12 +874,14 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask,
 		return -EINVAL;
 
 	if (flags & MPOL_F_MEMS_ALLOWED) {
+		unsigned long irqflags;
+
 		if (flags & (MPOL_F_NODE|MPOL_F_ADDR))
 			return -EINVAL;
 		*policy = 0;	/* just so it's initialized */
-		task_lock(current);
+		task_lock(current, &irqflags);
 		*nmask  = cpuset_current_mems_allowed;
-		task_unlock(current);
+		task_unlock(current, &irqflags);
 		return 0;
 	}
 
@@ -937,9 +940,11 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask,
 		if (mpol_store_user_nodemask(pol)) {
 			*nmask = pol->w.user_nodemask;
 		} else {
-			task_lock(current);
+			unsigned long irqflags;
+
+			task_lock(current, &irqflags);
 			get_policy_nodemask(pol, nmask);
-			task_unlock(current);
+			task_unlock(current, &irqflags);
 		}
 	}
 
@@ -1221,10 +1226,12 @@ static long do_mbind(unsigned long start, unsigned long len,
 	{
 		NODEMASK_SCRATCH(scratch);
 		if (scratch) {
+			unsigned long irqflags;
+
 			down_write(&mm->mmap_sem);
-			task_lock(current);
+			task_lock(current, &irqflags);
 			err = mpol_set_nodemask(new, nmask, scratch);
-			task_unlock(current);
+			task_unlock(current, &irqflags);
 			if (err)
 				up_write(&mm->mmap_sem);
 		} else
@@ -1876,11 +1883,12 @@ bool init_nodemask_of_mempolicy(nodemask_t *mask)
 {
 	struct mempolicy *mempolicy;
 	int nid;
+	unsigned long irqflags;
 
 	if (!(mask && current->mempolicy))
 		return false;
 
-	task_lock(current);
+	task_lock(current, &irqflags);
 	mempolicy = current->mempolicy;
 	switch (mempolicy->mode) {
 	case MPOL_PREFERRED:
@@ -1900,7 +1908,7 @@ bool init_nodemask_of_mempolicy(nodemask_t *mask)
 	default:
 		BUG();
 	}
-	task_unlock(current);
+	task_unlock(current, &irqflags);
 
 	return true;
 }
@@ -1921,10 +1929,11 @@ bool mempolicy_nodemask_intersects(struct task_struct *tsk,
 {
 	struct mempolicy *mempolicy;
 	bool ret = true;
+	unsigned long irqflags;
 
 	if (!mask)
 		return ret;
-	task_lock(tsk);
+	task_lock(tsk, &irqflags);
 	mempolicy = tsk->mempolicy;
 	if (!mempolicy)
 		goto out;
@@ -1946,7 +1955,7 @@ bool mempolicy_nodemask_intersects(struct task_struct *tsk,
 		BUG();
 	}
 out:
-	task_unlock(tsk);
+	task_unlock(tsk, &irqflags);
 	return ret;
 }
 
@@ -2127,9 +2136,11 @@ struct mempolicy *__mpol_dup(struct mempolicy *old)
 
 	/* task's mempolicy is protected by alloc_lock */
 	if (old == current->mempolicy) {
-		task_lock(current);
+		unsigned long irqflags;
+
+		task_lock(current, &irqflags);
 		*new = *old;
-		task_unlock(current);
+		task_unlock(current, &irqflags);
 	} else
 		*new = *old;
 
@@ -2474,6 +2485,7 @@ void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol)
 		struct vm_area_struct pvma;
 		struct mempolicy *new;
 		NODEMASK_SCRATCH(scratch);
+		unsigned long irqflags;
 
 		if (!scratch)
 			goto put_mpol;
@@ -2482,9 +2494,9 @@ void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol)
 		if (IS_ERR(new))
 			goto free_scratch; /* no valid nodemask intersection */
 
-		task_lock(current);
+		task_lock(current, &irqflags);
 		ret = mpol_set_nodemask(new, &mpol->w.user_nodemask, scratch);
-		task_unlock(current);
+		task_unlock(current, &irqflags);
 		if (ret)
 			goto put_new;
 
diff --git a/mm/mmu_context.c b/mm/mmu_context.c
index f802c2d..0651d21 100644
--- a/mm/mmu_context.c
+++ b/mm/mmu_context.c
@@ -21,8 +21,9 @@ void use_mm(struct mm_struct *mm)
 {
 	struct mm_struct *active_mm;
 	struct task_struct *tsk = current;
+	unsigned long irqflags;
 
-	task_lock(tsk);
+	task_lock(tsk, &irqflags);
 	active_mm = tsk->active_mm;
 	if (active_mm != mm) {
 		atomic_inc(&mm->mm_count);
@@ -30,7 +31,7 @@ void use_mm(struct mm_struct *mm)
 	}
 	tsk->mm = mm;
 	switch_mm(active_mm, mm, tsk);
-	task_unlock(tsk);
+	task_unlock(tsk, &irqflags);
 #ifdef finish_arch_post_lock_switch
 	finish_arch_post_lock_switch();
 #endif
@@ -51,12 +52,13 @@ EXPORT_SYMBOL_GPL(use_mm);
 void unuse_mm(struct mm_struct *mm)
 {
 	struct task_struct *tsk = current;
+	unsigned long irqflags;
 
-	task_lock(tsk);
+	task_lock(tsk, &irqflags);
 	sync_mm_rss(mm);
 	tsk->mm = NULL;
 	/* active_mm is still 'mm' */
 	enter_lazy_tlb(mm, tsk);
-	task_unlock(tsk);
+	task_unlock(tsk, &irqflags);
 }
 EXPORT_SYMBOL_GPL(unuse_mm);
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 8634958..e8039784 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -104,17 +104,18 @@ static bool has_intersects_mems_allowed(struct task_struct *tsk,
  * pointer.  Return p, or any of its subthreads with a valid ->mm, with
  * task_lock() held.
  */
-struct task_struct *find_lock_task_mm(struct task_struct *p)
+struct task_struct *find_lock_task_mm(struct task_struct *p,
+						unsigned long *irqflags)
 {
 	struct task_struct *t;
 
 	rcu_read_lock();
 
 	for_each_thread(p, t) {
-		task_lock(t);
+		task_lock(t, irqflags);
 		if (likely(t->mm))
 			goto found;
-		task_unlock(t);
+		task_unlock(t, irqflags);
 	}
 	t = NULL;
 found:
@@ -166,17 +167,18 @@ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg,
 {
 	long points;
 	long adj;
+	unsigned long irqflags;
 
 	if (oom_unkillable_task(p, memcg, nodemask))
 		return 0;
 
-	p = find_lock_task_mm(p);
+	p = find_lock_task_mm(p, &irqflags);
 	if (!p)
 		return 0;
 
 	adj = (long)p->signal->oom_score_adj;
 	if (adj == OOM_SCORE_ADJ_MIN) {
-		task_unlock(p);
+		task_unlock(p, &irqflags);
 		return 0;
 	}
 
@@ -186,7 +188,7 @@ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg,
 	 */
 	points = get_mm_rss(p->mm) + get_mm_counter(p->mm, MM_SWAPENTS) +
 		atomic_long_read(&p->mm->nr_ptes) + mm_nr_pmds(p->mm);
-	task_unlock(p);
+	task_unlock(p, &irqflags);
 
 	/*
 	 * Root processes get 3% bonus, just like the __vm_enough_memory()
@@ -356,6 +358,7 @@ static void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask)
 {
 	struct task_struct *p;
 	struct task_struct *task;
+	unsigned long irqflags;
 
 	pr_info("[ pid ]   uid  tgid total_vm      rss nr_ptes nr_pmds swapents oom_score_adj name\n");
 	rcu_read_lock();
@@ -363,7 +366,7 @@ static void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask)
 		if (oom_unkillable_task(p, memcg, nodemask))
 			continue;
 
-		task = find_lock_task_mm(p);
+		task = find_lock_task_mm(p, &irqflags);
 		if (!task) {
 			/*
 			 * This is a kthread or all of p's threads have already
@@ -380,7 +383,7 @@ static void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask)
 			mm_nr_pmds(task->mm),
 			get_mm_counter(task->mm, MM_SWAPENTS),
 			task->signal->oom_score_adj, task->comm);
-		task_unlock(task);
+		task_unlock(task, &irqflags);
 	}
 	rcu_read_unlock();
 }
@@ -432,6 +435,7 @@ static bool __oom_reap_task(struct task_struct *tsk)
 	struct zap_details details = {.check_swap_entries = true,
 				      .ignore_dirty = true};
 	bool ret = true;
+	unsigned long irqflags;
 
 	/*
 	 * Make sure we find the associated mm_struct even when the particular
@@ -439,17 +443,17 @@ static bool __oom_reap_task(struct task_struct *tsk)
 	 * We might have race with exit path so consider our work done if there
 	 * is no mm.
 	 */
-	p = find_lock_task_mm(tsk);
+	p = find_lock_task_mm(tsk, &irqflags);
 	if (!p)
 		return true;
 
 	mm = p->mm;
 	if (!atomic_inc_not_zero(&mm->mm_users)) {
-		task_unlock(p);
+		task_unlock(p, &irqflags);
 		return true;
 	}
 
-	task_unlock(p);
+	task_unlock(p, &irqflags);
 
 	if (!down_read_trylock(&mm->mmap_sem)) {
 		ret = false;
@@ -686,19 +690,20 @@ void oom_kill_process(struct oom_control *oc, struct task_struct *p,
 	static DEFINE_RATELIMIT_STATE(oom_rs, DEFAULT_RATELIMIT_INTERVAL,
 					      DEFAULT_RATELIMIT_BURST);
 	bool can_oom_reap = true;
+	unsigned long irqflags;
 
 	/*
 	 * If the task is already exiting, don't alarm the sysadmin or kill
 	 * its children or threads, just set TIF_MEMDIE so it can die quickly
 	 */
-	task_lock(p);
+	task_lock(p, &irqflags);
 	if (p->mm && task_will_free_mem(p)) {
 		mark_oom_victim(p);
-		task_unlock(p);
+		task_unlock(p, &irqflags);
 		put_task_struct(p);
 		return;
 	}
-	task_unlock(p);
+	task_unlock(p, &irqflags);
 
 	if (__ratelimit(&oom_rs))
 		dump_header(oc, p, memcg);
@@ -734,7 +739,7 @@ void oom_kill_process(struct oom_control *oc, struct task_struct *p,
 	}
 	read_unlock(&tasklist_lock);
 
-	p = find_lock_task_mm(victim);
+	p = find_lock_task_mm(victim, &irqflags);
 	if (!p) {
 		put_task_struct(victim);
 		return;
@@ -759,7 +764,7 @@ void oom_kill_process(struct oom_control *oc, struct task_struct *p,
 		K(get_mm_counter(victim->mm, MM_ANONPAGES)),
 		K(get_mm_counter(victim->mm, MM_FILEPAGES)),
 		K(get_mm_counter(victim->mm, MM_SHMEMPAGES)));
-	task_unlock(victim);
+	task_unlock(victim, &irqflags);
 
 	/*
 	 * Kill all user processes sharing victim->mm in other thread groups, if
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 2c2eb1b..421fccd 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -502,11 +502,13 @@ struct net *get_net_ns_by_pid(pid_t pid)
 	tsk = find_task_by_vpid(pid);
 	if (tsk) {
 		struct nsproxy *nsproxy;
-		task_lock(tsk);
+		unsigned long irqflags;
+
+		task_lock(tsk, &irqflags);
 		nsproxy = tsk->nsproxy;
 		if (nsproxy)
 			net = get_net(nsproxy->net_ns);
-		task_unlock(tsk);
+		task_unlock(tsk, &irqflags);
 	}
 	rcu_read_unlock();
 	return net;
@@ -963,12 +965,13 @@ static struct ns_common *netns_get(struct task_struct *task)
 {
 	struct net *net = NULL;
 	struct nsproxy *nsproxy;
+	unsigned long irqflags;
 
-	task_lock(task);
+	task_lock(task, &irqflags);
 	nsproxy = task->nsproxy;
 	if (nsproxy)
 		net = get_net(nsproxy->net_ns);
-	task_unlock(task);
+	task_unlock(task, &irqflags);
 
 	return net ? &net->ns : NULL;
 }
diff --git a/net/core/netclassid_cgroup.c b/net/core/netclassid_cgroup.c
index 11fce17..32482fd 100644
--- a/net/core/netclassid_cgroup.c
+++ b/net/core/netclassid_cgroup.c
@@ -76,9 +76,11 @@ static void update_classid(struct cgroup_subsys_state *css, void *v)
 
 	css_task_iter_start(css, &it);
 	while ((p = css_task_iter_next(&it))) {
-		task_lock(p);
+		unsigned long irqflags;
+
+		task_lock(p, &irqflags);
 		iterate_fd(p->files, 0, update_classid_sock, v);
-		task_unlock(p);
+		task_unlock(p, &irqflags);
 	}
 	css_task_iter_end(&it);
 }
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index 2ec86fc..e573c46 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -238,11 +238,12 @@ static void net_prio_attach(struct cgroup_taskset *tset)
 	struct cgroup_subsys_state *css;
 
 	cgroup_taskset_for_each(p, css, tset) {
+		unsigned long irqflags;
 		void *v = (void *)(unsigned long)css->cgroup->id;
 
-		task_lock(p);
+		task_lock(p, &irqflags);
 		iterate_fd(p->files, 0, update_netprio, v);
-		task_unlock(p);
+		task_unlock(p, &irqflags);
 	}
 }
 
-- 


             reply index

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-10 13:04 yhb [this message]
2016-07-11  9:30 ` James Hogan
2016-07-11 18:02 ` Leonid Yegoshin
2016-07-11 18:05   ` [PATCH] " Leonid Yegoshin
2016-07-11 18:07   ` James Hogan
2016-07-11 18:19     ` [PATCH] " Leonid Yegoshin
2016-07-11 19:21       ` James Hogan
2016-07-11 19:39         ` Leonid Yegoshin
2016-07-11 20:18           ` James Hogan

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=80B78A8B8FEE6145A87579E8435D78C30205D5F3@fzex.ruijie.com.cn \
    --to=yhb@ruijie.com.cn \
    --cc=linux-mips@linux-mips.org \
    --cc=ralf@linux-mips.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-MIPS Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-mips/0 linux-mips/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-mips linux-mips/ https://lore.kernel.org/linux-mips \
		linux-mips@vger.kernel.org linux-mips@archiver.kernel.org
	public-inbox-index linux-mips


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-mips


AGPL code for this site: git clone https://public-inbox.org/ public-inbox