)]}'
{
  "commit": "b2efa05265d62bc29f3a64400fad4b44340eedb8",
  "tree": "4555f0b5f0025c099997b81f7b3f8bc48b44220d",
  "parents": [
    "f1a4f4d35ff30a328d5ea28f6cc826b2083111d2"
  ],
  "author": {
    "name": "Tejun Heo",
    "email": "tj@kernel.org",
    "time": "Wed Dec 14 00:33:39 2011 +0100"
  },
  "committer": {
    "name": "Jens Axboe",
    "email": "axboe@kernel.dk",
    "time": "Wed Dec 14 00:33:39 2011 +0100"
  },
  "message": "block, cfq: unlink cfq_io_context\u0027s immediately\n\ncic is association between io_context and request_queue.  A cic is\nlinked from both ioc and q and should be destroyed when either one\ngoes away.  As ioc and q both have their own locks, locking becomes a\nbit complex - both orders work for removal from one but not from the\nother.\n\nCurrently, cfq tries to circumvent this locking order issue with RCU.\nioc-\u003elock nests inside queue_lock but the radix tree and cic\u0027s are\nalso protected by RCU allowing either side to walk their lists without\ngrabbing lock.\n\nThis rather unconventional use of RCU quickly devolves into extremely\nfragile convolution.  e.g. The following is from cfqd going away too\nsoon after ioc and q exits raced.\n\n general protection fault: 0000 [#1] PREEMPT SMP\n CPU 2\n Modules linked in:\n [   88.503444]\n Pid: 599, comm: hexdump Not tainted 3.1.0-rc10-work+ #158 Bochs Bochs\n RIP: 0010:[\u003cffffffff81397628\u003e]  [\u003cffffffff81397628\u003e] cfq_exit_single_io_context+0x58/0xf0\n ...\n Call Trace:\n  [\u003cffffffff81395a4a\u003e] call_for_each_cic+0x5a/0x90\n  [\u003cffffffff81395ab5\u003e] cfq_exit_io_context+0x15/0x20\n  [\u003cffffffff81389130\u003e] exit_io_context+0x100/0x140\n  [\u003cffffffff81098a29\u003e] do_exit+0x579/0x850\n  [\u003cffffffff81098d5b\u003e] do_group_exit+0x5b/0xd0\n  [\u003cffffffff81098de7\u003e] sys_exit_group+0x17/0x20\n  [\u003cffffffff81b02f2b\u003e] system_call_fastpath+0x16/0x1b\n\nThe only real hot path here is cic lookup during request\ninitialization and avoiding extra locking requires very confined use\nof RCU.  This patch makes cic removal from both ioc and request_queue\nperform double-locking and unlink immediately.\n\n* From q side, the change is almost trivial as ioc-\u003elock nests inside\n  queue_lock.  It just needs to grab each ioc-\u003elock as it walks\n  cic_list and unlink it.\n\n* From ioc side, it\u0027s a bit more difficult because of inversed lock\n  order.  ioc needs its lock to walk its cic_list but can\u0027t grab the\n  matching queue_lock and needs to perform unlock-relock dancing.\n\n  Unlinking is now wholly done from put_io_context() and fast path is\n  optimized by using the queue_lock the caller already holds, which is\n  by far the most common case.  If the ioc accessed multiple devices,\n  it tries with trylock.  In unlikely cases of fast path failure, it\n  falls back to full double-locking dance from workqueue.\n\nDouble-locking isn\u0027t the prettiest thing in the world but it\u0027s *far*\nsimpler and more understandable than RCU trick without adding any\nmeaningful overhead.\n\nThis still leaves a lot of now unnecessary RCU logics.  Future patches\nwill trim them.\n\n-v2: Vivek pointed out that cic-\u003eq was being dereferenced after\n     cic-\u003erelease() was called.  Updated to use local variable @this_q\n     instead.\n\nSigned-off-by: Tejun Heo \u003ctj@kernel.org\u003e\nCc: Vivek Goyal \u003cvgoyal@redhat.com\u003e\nSigned-off-by: Jens Axboe \u003caxboe@kernel.dk\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "dc00835aab6a4b17c2fd4ddd48dec663bff3c98e",
      "old_mode": 33188,
      "old_path": "block/blk-cgroup.c",
      "new_id": "27886935804966b8246c3495898cdaec1088b9f6",
      "new_mode": 33188,
      "new_path": "block/blk-cgroup.c"
    },
    {
      "type": "modify",
      "old_id": "6f59fbad93d9b19fc56dca824b7aa8a4b9241cf3",
      "old_mode": 33188,
      "old_path": "block/blk-ioc.c",
      "new_id": "fb23965595da6a34f5965074004ba73887476561",
      "new_mode": 33188,
      "new_path": "block/blk-ioc.c"
    },
    {
      "type": "modify",
      "old_id": "e617b088c59b2e46803f3686a227a22f1c9d91f0",
      "old_mode": 33188,
      "old_path": "block/cfq-iosched.c",
      "new_id": "6cc606560402278feffb36b025962f60593855ec",
      "new_mode": 33188,
      "new_path": "block/cfq-iosched.c"
    },
    {
      "type": "modify",
      "old_id": "0f1b9515213b14e5f4c2e8606efea4ff1a8c2fc4",
      "old_mode": 33188,
      "old_path": "fs/ioprio.c",
      "new_id": "f84b380d65e5d1a1898248bdb7a77dd3bc8b5aa4",
      "new_mode": 33188,
      "new_path": "fs/ioprio.c"
    },
    {
      "type": "modify",
      "old_id": "d1b6f4ed1f962ef1604674c5ec3f2ba4dc21412b",
      "old_mode": 33188,
      "old_path": "include/linux/blkdev.h",
      "new_id": "65c2f8c700894368543f5c9b92e00aa6f1f58f04",
      "new_mode": 33188,
      "new_path": "include/linux/blkdev.h"
    },
    {
      "type": "modify",
      "old_id": "2c2b6da96b3c5de2a1e5c916a216ffeb8faaecdb",
      "old_mode": 33188,
      "old_path": "include/linux/iocontext.h",
      "new_id": "01e8631287806fcac2dc16658b6b14da9c7a0e04",
      "new_mode": 33188,
      "new_path": "include/linux/iocontext.h"
    },
    {
      "type": "modify",
      "old_id": "5bcfc739bb7c628039c9f0df17d1be6960a3300f",
      "old_mode": 33188,
      "old_path": "kernel/fork.c",
      "new_id": "2753449f2038af61f6ac1cb1e3f305adbd3063f0",
      "new_mode": 33188,
      "new_path": "kernel/fork.c"
    }
  ]
}
