)]}'
{
  "commit": "b5740f4b2cb3503b436925eb2242bc3d75cd3dfe",
  "tree": "c7e00c7be916f5fdc01109257752fc408b2b2d97",
  "parents": [
    "71325960d16cd68ea0e22a8da15b2495b0f363f7"
  ],
  "author": {
    "name": "Yasunori Goto",
    "email": "y-goto@jp.fujitsu.com",
    "time": "Tue Jan 17 17:40:31 2012 +0900"
  },
  "committer": {
    "name": "Ingo Molnar",
    "email": "mingo@elte.hu",
    "time": "Fri Jan 27 11:55:36 2012 +0100"
  },
  "message": "sched: Fix ancient race in do_exit()\n\ntry_to_wake_up() has a problem which may change status from TASK_DEAD to\nTASK_RUNNING in race condition with SMI or guest environment of virtual\nmachine. As a result, exited task is scheduled() again and panic occurs.\n\nHere is the sequence how it occurs:\n\n ----------------------------------+-----------------------------\n                                   |\n            CPU A                  |             CPU B\n ----------------------------------+-----------------------------\n\nTASK A calls exit()....\n\ndo_exit()\n\n  exit_mm()\n    down_read(mm-\u003emmap_sem);\n\n    rwsem_down_failed_common()\n\n      set TASK_UNINTERRUPTIBLE\n      set waiter.task \u003c\u003d task A\n      list_add to sem-\u003ewait_list\n           :\n      raw_spin_unlock_irq()\n      (I/O interruption occured)\n\n                                      __rwsem_do_wake(mmap_sem)\n\n                                        list_del(\u0026waiter-\u003elist);\n                                        waiter-\u003etask \u003d NULL\n                                        wake_up_process(task A)\n                                          try_to_wake_up()\n                                             (task is still\n                                               TASK_UNINTERRUPTIBLE)\n                                              p-\u003eon_rq is still 1.)\n\n                                              ttwu_do_wakeup()\n                                                 (*A)\n                                                   :\n     (I/O interruption handler finished)\n\n      if (!waiter.task)\n          schedule() is not called\n          due to waiter.task is NULL.\n\n      tsk-\u003estate \u003d TASK_RUNNING\n\n          :\n                                              check_preempt_curr();\n                                                  :\n  task-\u003estate \u003d TASK_DEAD\n                                              (*B)\n                                        \u003c---    set TASK_RUNNING (*C)\n\n     schedule()\n     (exit task is running again)\n     BUG_ON() is called!\n --------------------------------------------------------\n\nThe execution time between (*A) and (*B) is usually very short,\nbecause the interruption is disabled, and setting TASK_RUNNING at (*C)\nmust be executed before setting TASK_DEAD.\n\nHOWEVER, if SMI is interrupted between (*A) and (*B),\n(*C) is able to execute AFTER setting TASK_DEAD!\nThen, exited task is scheduled again, and BUG_ON() is called....\n\nIf the system works on guest system of virtual machine, the time\nbetween (*A) and (*B) may be also long due to scheduling of hypervisor,\nand same phenomenon can occur.\n\nBy this patch, do_exit() waits for releasing task-\u003epi_lock which is used\nin try_to_wake_up(). It guarantees the task becomes TASK_DEAD after\nwaking up.\n\nSigned-off-by: Yasunori Goto \u003cy-goto@jp.fujitsu.com\u003e\nAcked-by: Oleg Nesterov \u003coleg@redhat.com\u003e\nSigned-off-by: Peter Zijlstra \u003ca.p.zijlstra@chello.nl\u003e\nCc: Linus Torvalds \u003ctorvalds@linux-foundation.org\u003e\nCc: Andrew Morton \u003cakpm@linux-foundation.org\u003e\nLink: http://lkml.kernel.org/r/20120117174031.3118.E1E9C6FF@jp.fujitsu.com\nSigned-off-by: Ingo Molnar \u003cmingo@elte.hu\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "294b1709170d1e890c80d064c65d38c1b12a88c1",
      "old_mode": 33188,
      "old_path": "kernel/exit.c",
      "new_id": "4b4042f9bc6ade78a14199eb4ce96dc4ce6236b3",
      "new_mode": 33188,
      "new_path": "kernel/exit.c"
    }
  ]
}
