thermal/drivers/sprd: Fix return value of sprd_thm_probe()
[linux-2.6-microblaze.git] / mm / memory-failure.c
index ababa36..47b8ccb 100644 (file)
@@ -212,15 +212,13 @@ static int kill_proc(struct to_kill *tk, unsigned long pfn, int flags)
        short addr_lsb = tk->size_shift;
        int ret = 0;
 
-       if ((t->mm == current->mm) || !(flags & MF_ACTION_REQUIRED))
-               pr_err("Memory failure: %#lx: Sending SIGBUS to %s:%d due to hardware memory corruption\n",
+       pr_err("Memory failure: %#lx: Sending SIGBUS to %s:%d due to hardware memory corruption\n",
                        pfn, t->comm, t->pid);
 
        if (flags & MF_ACTION_REQUIRED) {
-               if (t->mm == current->mm)
-                       ret = force_sig_mceerr(BUS_MCEERR_AR,
+               WARN_ON_ONCE(t != current);
+               ret = force_sig_mceerr(BUS_MCEERR_AR,
                                         (void __user *)tk->addr, addr_lsb);
-               /* send no signal to non-current processes */
        } else {
                /*
                 * Don't use force here, it's convenient if the signal
@@ -402,9 +400,15 @@ static struct task_struct *find_early_kill_thread(struct task_struct *tsk)
 {
        struct task_struct *t;
 
-       for_each_thread(tsk, t)
-               if ((t->flags & PF_MCE_PROCESS) && (t->flags & PF_MCE_EARLY))
-                       return t;
+       for_each_thread(tsk, t) {
+               if (t->flags & PF_MCE_PROCESS) {
+                       if (t->flags & PF_MCE_EARLY)
+                               return t;
+               } else {
+                       if (sysctl_memory_failure_early_kill)
+                               return t;
+               }
+       }
        return NULL;
 }
 
@@ -413,21 +417,26 @@ static struct task_struct *find_early_kill_thread(struct task_struct *tsk)
  * to be signaled when some page under the process is hwpoisoned.
  * Return task_struct of the dedicated thread (main thread unless explicitly
  * specified) if the process is "early kill," and otherwise returns NULL.
+ *
+ * Note that the above is true for Action Optional case, but not for Action
+ * Required case where SIGBUS should sent only to the current thread.
  */
 static struct task_struct *task_early_kill(struct task_struct *tsk,
                                           int force_early)
 {
-       struct task_struct *t;
        if (!tsk->mm)
                return NULL;
-       if (force_early)
-               return tsk;
-       t = find_early_kill_thread(tsk);
-       if (t)
-               return t;
-       if (sysctl_memory_failure_early_kill)
-               return tsk;
-       return NULL;
+       if (force_early) {
+               /*
+                * Comparing ->mm here because current task might represent
+                * a subthread, while tsk always points to the main thread.
+                */
+               if (tsk->mm == current->mm)
+                       return current;
+               else
+                       return NULL;
+       }
+       return find_early_kill_thread(tsk);
 }
 
 /*