)]}'
{
  "commit": "626cf236608505d376e4799adb4f7eb00a8594af",
  "tree": "eb0421fec1a7fed05cd9ea785bd18b5f40c80971",
  "parents": [
    "5cde7656d0dd222170eb0250bd1f70c9018fd438"
  ],
  "author": {
    "name": "Hans Verkuil",
    "email": "hans.verkuil@cisco.com",
    "time": "Fri Mar 23 15:02:27 2012 -0700"
  },
  "committer": {
    "name": "Linus Torvalds",
    "email": "torvalds@linux-foundation.org",
    "time": "Fri Mar 23 16:58:38 2012 -0700"
  },
  "message": "poll: add poll_requested_events() and poll_does_not_wait() functions\n\nIn some cases the poll() implementation in a driver has to do different\nthings depending on the events the caller wants to poll for.  An example\nis when a driver needs to start a DMA engine if the caller polls for\nPOLLIN, but doesn\u0027t want to do that if POLLIN is not requested but instead\nonly POLLOUT or POLLPRI is requested.  This is something that can happen\nin the video4linux subsystem among others.\n\nUnfortunately, the current epoll/poll/select implementation doesn\u0027t\nprovide that information reliably.  The poll_table_struct does have it: it\nhas a key field with the event mask.  But once a poll() call matches one\nor more bits of that mask any following poll() calls are passed a NULL\npoll_table pointer.\n\nAlso, the eventpoll implementation always left the key field at ~0 instead\nof using the requested events mask.\n\nThis was changed in eventpoll.c so the key field now contains the actual\nevents that should be polled for as set by the caller.\n\nThe solution to the NULL poll_table pointer is to set the qproc field to\nNULL in poll_table once poll() matches the events, not the poll_table\npointer itself.  That way drivers can obtain the mask through a new\npoll_requested_events inline.\n\nThe poll_table_struct can still be NULL since some kernel code calls it\ninternally (netfs_state_poll() in ./drivers/staging/pohmelfs/netfs.h).  In\nthat case poll_requested_events() returns ~0 (i.e.  all events).\n\nVery rarely drivers might want to know whether poll_wait will actually\nwait.  If another earlier file descriptor in the set already matched the\nevents the caller wanted to wait for, then the kernel will return from the\nselect() call without waiting.  This might be useful information in order\nto avoid doing expensive work.\n\nA new helper function poll_does_not_wait() is added that drivers can use\nto detect this situation.  This is now used in sock_poll_wait() in\ninclude/net/sock.h.  This was the only place in the kernel that needed\nthis information.\n\nDrivers should no longer access any of the poll_table internals, but use\nthe poll_requested_events() and poll_does_not_wait() access functions\ninstead.  In order to enforce that the poll_table fields are now prepended\nwith an underscore and a comment was added warning against using them\ndirectly.\n\nThis required a change in unix_dgram_poll() in unix/af_unix.c which used\nthe key field to get the requested events.  It\u0027s been replaced by a call\nto poll_requested_events().\n\nFor qproc it was especially important to change its name since the\nbehavior of that field changes with this patch since this function pointer\ncan now be NULL when that wasn\u0027t possible in the past.\n\nAny driver accessing the qproc or key fields directly will now fail to compile.\n\nSome notes regarding the correctness of this patch: the driver\u0027s poll()\nfunction is called with a \u0027struct poll_table_struct *wait\u0027 argument.  This\npointer may or may not be NULL, drivers can never rely on it being one or\nthe other as that depends on whether or not an earlier file descriptor in\nthe select()\u0027s fdset matched the requested events.\n\nThere are only three things a driver can do with the wait argument:\n\n1) obtain the key field:\n\n\tevents \u003d wait ? wait-\u003ekey : ~0;\n\n   This will still work although it should be replaced with the new\n   poll_requested_events() function (which does exactly the same).\n   This will now even work better, since wait is no longer set to NULL\n   unnecessarily.\n\n2) use the qproc callback. This could be deadly since qproc can now be\n   NULL. Renaming qproc should prevent this from happening. There are no\n   kernel drivers that actually access this callback directly, BTW.\n\n3) test whether wait \u003d\u003d NULL to determine whether poll would return without\n   waiting. This is no longer sufficient as the correct test is now\n   wait \u003d\u003d NULL || wait-\u003e_qproc \u003d\u003d NULL.\n\n   However, the worst that can happen here is a slight performance hit in\n   the case where wait !\u003d NULL and wait-\u003e_qproc \u003d\u003d NULL. In that case the\n   driver will assume that poll_wait() will actually add the fd to the set\n   of waiting file descriptors. Of course, poll_wait() will not do that\n   since it tests for wait-\u003e_qproc. This will not break anything, though.\n\n   There is only one place in the whole kernel where this happens\n   (sock_poll_wait() in include/net/sock.h) and that code will be replaced\n   by a call to poll_does_not_wait() in the next patch.\n\n   Note that even if wait-\u003e_qproc !\u003d NULL drivers cannot rely on poll_wait()\n   actually waiting. The next file descriptor from the set might match the\n   event mask and thus any possible waits will never happen.\n\nSigned-off-by: Hans Verkuil \u003chans.verkuil@cisco.com\u003e\nReviewed-by: Jonathan Corbet \u003ccorbet@lwn.net\u003e\nReviewed-by: Al Viro \u003cviro@zeniv.linux.org.uk\u003e\nCc: Davide Libenzi \u003cdavidel@xmailserver.org\u003e\nSigned-off-by: Hans de Goede \u003chdegoede@redhat.com\u003e\nCc: Mauro Carvalho Chehab \u003cmchehab@infradead.org\u003e\nCc: David Miller \u003cdavem@davemloft.net\u003e\nCc: Eric Dumazet \u003ceric.dumazet@gmail.com\u003e\nSigned-off-by: Andrew Morton \u003cakpm@linux-foundation.org\u003e\nSigned-off-by: Linus Torvalds \u003ctorvalds@linux-foundation.org\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "4d9d3a45e35647a19d9182e28422c397f654abb5",
      "old_mode": 33188,
      "old_path": "fs/eventpoll.c",
      "new_id": "ca300071e79c1c1abcd3eb3f58fc8f24ea558dc0",
      "new_mode": 33188,
      "new_path": "fs/eventpoll.c"
    },
    {
      "type": "modify",
      "old_id": "e782258d0de3cec01c6767aa5cb2b2684e1077ac",
      "old_mode": 33188,
      "old_path": "fs/select.c",
      "new_id": "ecfd0b125ba28f22597466f62a5cde273e440cb9",
      "new_mode": 33188,
      "new_path": "fs/select.c"
    },
    {
      "type": "modify",
      "old_id": "cf40010ce0cdf5066b70f9c26e1f951a3c6ed7fa",
      "old_mode": 33188,
      "old_path": "include/linux/poll.h",
      "new_id": "48fe8bc398d1a388c55ee7b99041ff5a84b25ea3",
      "new_mode": 33188,
      "new_path": "include/linux/poll.h"
    },
    {
      "type": "modify",
      "old_id": "04bc0b30e9e9067320eaeb7c43d1def462771e6d",
      "old_mode": 33188,
      "old_path": "include/net/sock.h",
      "new_id": "a6ba1f8871fda3077183717a1e099cd5161b555c",
      "new_mode": 33188,
      "new_path": "include/net/sock.h"
    },
    {
      "type": "modify",
      "old_id": "eb4277c3318875ca0799dcbaf597f735709e0631",
      "old_mode": 33188,
      "old_path": "net/unix/af_unix.c",
      "new_id": "d510353ef4310598b031b5122ecb99b2b719ad53",
      "new_mode": 33188,
      "new_path": "net/unix/af_unix.c"
    }
  ]
}
