)]}'
{
  "commit": "170d13ca3a2fdaaa0283399247631b76b441cca2",
  "tree": "d93b8d71969e9e77ee7e9854d49fe4cb6ac2e978",
  "parents": [
    "a959dc88f9c8900296ccf13e2f3e1cbc555a8917"
  ],
  "author": {
    "name": "Linus Torvalds",
    "email": "torvalds@linux-foundation.org",
    "time": "Fri Jan 04 17:52:49 2019 -0800"
  },
  "committer": {
    "name": "Linus Torvalds",
    "email": "torvalds@linux-foundation.org",
    "time": "Fri Jan 04 18:15:33 2019 -0800"
  },
  "message": "x86: re-introduce non-generic memcpy_{to,from}io\n\nThis has been broken forever, and nobody ever really noticed because\nit\u0027s purely a performance issue.\n\nLong long ago, in commit 6175ddf06b61 (\"x86: Clean up mem*io functions\")\nBrian Gerst simplified the memory copies to and from iomem, since on\nx86, the instructions to access iomem are exactly the same as the\nregular instructions.\n\nThat is technically true, and things worked, and nobody said anything.\nBesides, back then the regular memcpy was pretty simple and worked fine.\n\nNobody noticed except for David Laight, that is.  David has a testing a\nTLP monitor he was writing for an FPGA, and has been occasionally\ncomplaining about how memcpy_toio() writes things one byte at a time.\n\nWhich is completely unacceptable from a performance standpoint, even if\nit happens to technically work.\n\nThe reason it\u0027s writing one byte at a time is because while it\u0027s\ntechnically true that accesses to iomem are the same as accesses to\nregular memory on x86, the _granularity_ (and ordering) of accesses\nmatter to iomem in ways that they don\u0027t matter to regular cached memory.\n\nIn particular, when ERMS is set, we default to using \"rep movsb\" for\nlarger memory copies.  That is indeed perfectly fine for real memory,\nsince the whole point is that the CPU is going to do cacheline\noptimizations and executes the memory copy efficiently for cached\nmemory.\n\nWith iomem? Not so much.  With iomem, \"rep movsb\" will indeed work, but\nit will copy things one byte at a time. Slowly and ponderously.\n\nNow, originally, back in 2010 when commit 6175ddf06b61 was done, we\ndidn\u0027t use ERMS, and this was much less noticeable.\n\nOur normal memcpy() was simpler in other ways too.\n\nBecause in fact, it\u0027s not just about using the string instructions.  Our\nmemcpy() these days does things like \"read and write overlapping values\"\nto handle the last bytes of the copy.  Again, for normal memory,\noverlapping accesses isn\u0027t an issue.  For iomem? It can be.\n\nSo this re-introduces the specialized memcpy_toio(), memcpy_fromio() and\nmemset_io() functions.  It doesn\u0027t particularly optimize them, but it\ntries to at least not be horrid, or do overlapping accesses.  In fact,\nthis uses the existing __inline_memcpy() function that we still had\nlying around that uses our very traditional \"rep movsl\" loop followed by\nmovsw/movsb for the final bytes.\n\nSomebody may decide to try to improve on it, but if we\u0027ve gone almost a\ndecade with only one person really ever noticing and complaining, maybe\nit\u0027s not worth worrying about further, once it\u0027s not _completely_ broken?\n\nReported-by: David Laight \u003cDavid.Laight@aculab.com\u003e\nSigned-off-by: Linus Torvalds \u003ctorvalds@linux-foundation.org\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "832da8229cc78019d3a790346e764ca630b1c03e",
      "old_mode": 33188,
      "old_path": "arch/x86/include/asm/io.h",
      "new_id": "686247db3106f2b01e058ff6ab3e7a20948b2ddf",
      "new_mode": 33188,
      "new_path": "arch/x86/include/asm/io.h"
    },
    {
      "type": "modify",
      "old_id": "7ad41bfcc16cfa32cf2b59312ed2cec2a972c873",
      "old_mode": 33188,
      "old_path": "arch/x86/include/asm/string_64.h",
      "new_id": "4e4194e21a097e1a9e052580a5d5e50db33cbbf0",
      "new_mode": 33188,
      "new_path": "arch/x86/include/asm/string_64.h"
    },
    {
      "type": "modify",
      "old_id": "25a972c61b0ae9816a817eb9681f4cd374e9e32a",
      "old_mode": 33188,
      "old_path": "arch/x86/lib/Makefile",
      "new_id": "ce28829f12811ff5a3b482ab3cd2867c57630719",
      "new_mode": 33188,
      "new_path": "arch/x86/lib/Makefile"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "66894675f3c8d3ac65c4efdae5039d904110c9b2",
      "new_mode": 33188,
      "new_path": "arch/x86/lib/iomem.c"
    }
  ]
}
