)]}'
{
  "commit": "d585d0b9d73ed999cc7b8cf3cac4a5b01abb544e",
  "tree": "7cfb65304f92745eb7ca3e5fa9073bbba1cfa357",
  "parents": [
    "1702b52092e9a6d05398d3f9581ddc050ef00d06"
  ],
  "author": {
    "name": "Divyesh Shah",
    "email": "dpshah@google.com",
    "time": "Mon Jun 16 18:37:08 2008 +0200"
  },
  "committer": {
    "name": "Jens Axboe",
    "email": "jens.axboe@oracle.com",
    "time": "Tue Jul 01 09:06:42 2008 +0200"
  },
  "message": "block: Fix the starving writes bug in the anticipatory IO scheduler\n\nAS scheduler alternates between issuing read and write batches. It does\nthe batch switch only after all requests from the previous batch are\ncompleted.\n\nWhen switching to a write batch, if there is an on-going read request,\nit waits for its completion and indicates its intention of switching by\nsetting ad-\u003echanged_batch and the new direction but does not update the\nbatch_expire_time for the new write batch which it does in the case of\nno previous pending requests.\nOn completion of the read request, it sees that we were waiting for the\nswitch and schedules work for kblockd right away and resets the\nad-\u003echanged_data flag.\nNow when kblockd enters dispatch_request where it is expected to pick\nup a write request, it in turn ends the write batch because the\nbatch_expire_timer was not updated and shows the expire timestamp for\nthe previous batch.\n\nThis results in the write starvation for all the cases where there is\nthe intention for switching to a write batch, but there is a previous\nin-flight read request and the batch gets reverted to a read_batch\nright away.\n\nThis also holds true in the reverse case (switching from a write batch\nto a read batch with an in-flight write request).\n\nI\u0027ve checked that this bug exists on 2.6.11, 2.6.18, 2.6.24 and\nlinux-2.6-block git HEAD. I\u0027ve tested the fix on x86 platforms with\nSCSI drives where the driver asks for the next request while a current\nrequest is in-flight.\n\nThis patch is based off linux-2.6-block git HEAD.\n\nBug reproduction:\nA simple scenario which reproduces this bug is:\n- dd if\u003d/dev/hda3 of\u003d/dev/null \u0026\n- lilo\n   The lilo takes forever to complete.\n\nThis can also be reproduced fairly easily with the earlier dd and\nanother test\nprogram doing msync().\n\nThe example test program below should print out a message after every\niteration\nbut it simply hangs forever. With this bugfix it makes forward progress.\n\n\u003d\u003d\u003d\u003d\nExample test program using msync() (thanks to suleiman AT google DOT\ncom)\n\ninline uint64_t\nrdtsc(void)\n{\n         int64_t tsc;\n\n         __asm __volatile(\"rdtsc\" : \"\u003dA\" (tsc));\n         return (tsc);\n}\n\nint\nmain(int argc, char **argv)\n{\n         struct stat st;\n         uint64_t e, s, t;\n         char *p, q;\n         long i;\n         int fd;\n\n         if (argc \u003c 2) {\n                 printf(\"Usage: %s \u003cfile\u003e\\n\", argv[0]);\n                 return (1);\n         }\n\n         if ((fd \u003d open(argv[1], O_RDWR | O_NOATIME)) \u003c 0)\n                 err(1, \"open\");\n\n         if (fstat(fd, \u0026st) \u003c 0)\n                 err(1, \"fstat\");\n\n         p \u003d mmap(NULL, st.st_size, PROT_READ | PROT_WRITE,\nMAP_SHARED, fd, 0);\n\n         t \u003d 0;\n         for (i \u003d 0; i \u003c 1000; i++) {\n                 *p \u003d 0;\n                 msync(p, 4096, MS_SYNC);\n                 s \u003d rdtsc();\n                *p \u003d 0;\n                 __asm __volatile(\"\"::: \"memory\");\n                 e \u003d rdtsc();\n                 if (argc \u003e 2)\n                         printf(\"%d: %lld cycles %jd %jd\\n\",\n                                i, e - s, (intmax_t)s, (intmax_t)e);\n                 t +\u003d e - s;\n         }\n         printf(\"average time: %lld cycles\\n\", t / 1000);\n         return (0);\n}\n\nCc: \u003cstable@kernel.org\u003e\nAcked-by: Nick Piggin \u003cnpiggin@suse.de\u003e\nSigned-off-by: Jens Axboe \u003cjens.axboe@oracle.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "8c3946787dbbbaedd3381a195ab7851e84ec8272",
      "old_mode": 33188,
      "old_path": "block/as-iosched.c",
      "new_id": "743f33a01a079166c503167038d3657f8850dadd",
      "new_mode": 33188,
      "new_path": "block/as-iosched.c"
    }
  ]
}
