• Eric Biggers's avatar
    aio: keep poll requests on waitqueue until completed · 363bee27
    Eric Biggers authored
    Currently, aio_poll_wake() will always remove the poll request from the
    waitqueue.  Then, if aio_poll_complete_work() sees that none of the
    polled events are ready and the request isn't cancelled, it re-adds the
    request to the waitqueue.  (This can easily happen when polling a file
    that doesn't pass an event mask when waking up its waitqueue.)
    
    This is fundamentally broken for two reasons:
    
      1. If a wakeup occurs between vfs_poll() and the request being
         re-added to the waitqueue, it will be missed because the request
         wasn't on the waitqueue at the time.  Therefore, IOCB_CMD_POLL
         might never complete even if the polled file is ready.
    
      2. When the request isn't on the waitqueue, there is no way to be
         notified that the waitqueue is being freed (which happens when its
         lifetime is shorter than the struct file's).  This is supposed to
         happen via the waitqueue entries being woken up with POLLFREE.
    
    Therefore, leave the requests on the waitqueue until they are actually
    completed (or cancelled).  To keep track of when aio_poll_complete_work
    needs to be scheduled, use new fields in struct poll_iocb.  Remove the
    'done' field which is now redundant.
    
    Note that this is consistent with how sys_poll() and eventpoll work;
    their wakeup functions do *not* remove the waitqueue entries.
    
    Fixes: 2c14fa83 ("aio: implement IOCB_CMD_POLL")
    Cc: <stable@vger.kernel.org> # v4.18+
    Link: https://lore.kernel.org/r/20211209010455.42744-5-ebiggers@kernel.orgSigned-off-by: default avatarEric Biggers <ebiggers@google.com>
    363bee27
aio.c 58 KB