int                             bgid;
        size_t                          len;
        size_t                          done_io;
+       unsigned int                    flags;
 };
 
 struct io_open {
 {
        struct io_sr_msg *sr = &req->sr_msg;
 
-       if (unlikely(sqe->addr2 || sqe->file_index))
+       if (unlikely(sqe->file_index))
                return -EINVAL;
 
        sr->umsg = u64_to_user_ptr(READ_ONCE(sqe->addr));
        sr->len = READ_ONCE(sqe->len);
+       sr->flags = READ_ONCE(sqe->addr2);
+       if (sr->flags & ~IORING_RECVSEND_POLL_FIRST)
+               return -EINVAL;
        sr->msg_flags = READ_ONCE(sqe->msg_flags) | MSG_NOSIGNAL;
        if (sr->msg_flags & MSG_DONTWAIT)
                req->flags |= REQ_F_NOWAIT;
                kmsg = &iomsg;
        }
 
+       if (!(req->flags & REQ_F_POLLED) &&
+           (sr->flags & IORING_RECVSEND_POLL_FIRST))
+               return io_setup_async_msg(req, kmsg);
+
        flags = req->sr_msg.msg_flags;
        if (issue_flags & IO_URING_F_NONBLOCK)
                flags |= MSG_DONTWAIT;
        int min_ret = 0;
        int ret;
 
+       if (!(req->flags & REQ_F_POLLED) &&
+           (sr->flags & IORING_RECVSEND_POLL_FIRST))
+               return -EAGAIN;
+
        sock = sock_from_file(req->file);
        if (unlikely(!sock))
                return -ENOTSOCK;
 {
        struct io_sr_msg *sr = &req->sr_msg;
 
-       if (unlikely(sqe->addr2 || sqe->file_index))
+       if (unlikely(sqe->file_index))
                return -EINVAL;
 
        sr->umsg = u64_to_user_ptr(READ_ONCE(sqe->addr));
        sr->len = READ_ONCE(sqe->len);
+       sr->flags = READ_ONCE(sqe->addr2);
+       if (sr->flags & ~IORING_RECVSEND_POLL_FIRST)
+               return -EINVAL;
        sr->bgid = READ_ONCE(sqe->buf_group);
        sr->msg_flags = READ_ONCE(sqe->msg_flags) | MSG_NOSIGNAL;
        if (sr->msg_flags & MSG_DONTWAIT)
                kmsg = &iomsg;
        }
 
+       if (!(req->flags & REQ_F_POLLED) &&
+           (sr->flags & IORING_RECVSEND_POLL_FIRST))
+               return io_setup_async_msg(req, kmsg);
+
        if (req->flags & REQ_F_BUFFER_SELECT) {
                kbuf = io_recv_buffer_select(req, issue_flags);
                if (IS_ERR(kbuf))
        int ret, min_ret = 0;
        bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
 
+       if (!(req->flags & REQ_F_POLLED) &&
+           (sr->flags & IORING_RECVSEND_POLL_FIRST))
+               return -EAGAIN;
+
        sock = sock_from_file(req->file);
        if (unlikely(!sock))
                return -ENOTSOCK;
 
 #define IORING_ASYNC_CANCEL_FD (1U << 1)
 #define IORING_ASYNC_CANCEL_ANY        (1U << 2)
 
+/*
+ * send/sendmsg and recv/recvmsg flags (sqe->addr2)
+ *
+ * IORING_RECVSEND_POLL_FIRST  If set, instead of first attempting to send
+ *                             or receive and arm poll if that yields an
+ *                             -EAGAIN result, arm poll upfront and skip
+ *                             the initial transfer attempt.
+ */
+#define IORING_RECVSEND_POLL_FIRST     (1U << 0)
+
 /*
  * IO completion data structure (Completion Queue Entry)
  */