+
+ +
+
+ +
+ +

在io_uring中设置block的socket是否有意义?

+

先看IORING_OP_RECVMSG pdef 其支持pollin

+
    [IORING_OP_RECVMSG] = {
+        .needs_file     = 1,
+        .unbound_nonreg_file    = 1,
+        .pollin         = 1,
+        .buffer_select      = 1,
+        .ioprio         = 1,
+        .manual_alloc       = 1,
+        .name           = "RECVMSG",
+#if defined(CONFIG_NET)
+        .async_size     = sizeof(struct io_async_msghdr),
+        .prep           = io_recvmsg_prep,
+        .issue          = io_recvmsg,
+        .prep_async     = io_recvmsg_prep_async,
+        .cleanup        = io_sendmsg_recvmsg_cleanup,
+        .fail           = io_sendrecv_fail,
+
+

在第一次处理sqe的时候会强制使用IO_URING_F_NONBLOCK调用io_recvmsg

+
static inline void io_queue_sqe(struct io_kiocb *req)
+    __must_hold(&req->ctx->uring_lock)
+{
+    int ret;
+
+    ret = io_issue_sqe(req, IO_URING_F_NONBLOCK|IO_URING_F_COMPLETE_DEFER);
+
+    /*
+     * We async punt it if the file wasn't marked NOWAIT, or if the file
+     * doesn't support non-blocking read/write attempts
+     */
+    if (likely(!ret))
+        io_arm_ltimeout(req);
+    else
+        io_queue_async(req, ret);
+}
+
+

对于recv的实现 如果传入了IO_URING_F_NONBLOCK默认就会走MSG_DONTWAIT放进flag里面,对于recvmsg系统调用这个flag会非阻塞尝试下看看有没有数据

+

所以第一次的非阻塞尝试与是不是block的socket没关系

+
int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags)
+{
+   //....
+    bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
+   //....
+    flags = sr->msg_flags;
+    if (force_nonblock)
+        flags |= MSG_DONTWAIT;
+
+    //....
+    ret = __sys_recvmsg_sock(sock, &kmsg->msg, sr->umsg,
+                     kmsg->uaddr, flags);
+    //....                     
+ }
+
+

若取不到数据直接走了io_queue_async -> io_arm_poll_handler -> __io_arm_poll_handler

+
if (def->pollin) {
+//这里的recv op是支持 poll in的
+//最后会直接挂载到vfs的poll上去
+        mask |= EPOLLIN | EPOLLRDNORM;
+
+        /* If reading from MSG_ERRQUEUE using recvmsg, ignore POLLIN */
+        if (req->flags & REQ_F_CLEAR_POLLIN)
+            mask &= ~EPOLLIN;
+    } else {
+        mask |= EPOLLOUT | EPOLLWRNORM;
+    }
+    if (def->poll_exclusive)
+        mask |= EPOLLEXCLUSIVE;
+
+    apoll = io_req_alloc_apoll(req, issue_flags);
+    if (!apoll)
+        return IO_APOLL_ABORTED;
+    req->flags &= ~(REQ_F_SINGLE_POLL | REQ_F_DOUBLE_POLL);
+    req->flags |= REQ_F_POLLED;
+    ipt.pt._qproc = io_async_queue_proc;
+
+    io_kbuf_recycle(req, issue_flags);
+//简单来说就是 mask = vfs_poll(req->file, &ipt->pt) & poll->events;
+    ret = __io_arm_poll_handler(req, &apoll->poll, &ipt, mask, issue_flags);
+
+ + +
+ +
+
+
+ +

results matching ""

+
    + +
    +
    + +

    No results matching ""

    + +
    +
    +
    + +
    +