1
0
Fork 0
mirror of https://gitee.com/fantix/kloop.git synced 2024-05-19 08:48:07 +00:00

Fix a param set-zero bug when io_uring_enter returns EINVAL

Also we don't need to set `to_submit` when SQPOLL is set
This commit is contained in:
Fantix King 2022-06-25 14:46:28 -04:00
parent 081a2877b8
commit a1094281ec
No known key found for this signature in database
GPG key ID: 95304B04071CCDB4

View file

@ -95,7 +95,7 @@ cdef int ring_uninit(Ring* ring) nogil except 0:
return 1 return 1
cdef inline unsigned ring_sq_flush(SubmissionQueue* sq) nogil: cdef inline int ring_sq_flush(SubmissionQueue* sq) nogil:
cdef: cdef:
unsigned mask = sq.kring_mask[0] unsigned mask = sq.kring_mask[0]
unsigned tail = sq.ktail[0] unsigned tail = sq.ktail[0]
@ -108,20 +108,23 @@ cdef inline unsigned ring_sq_flush(SubmissionQueue* sq) nogil:
sq.sqe_head += 1 sq.sqe_head += 1
to_submit -= 1 to_submit -= 1
atomic.store_explicit(<atomic.uint*>sq.ktail, tail, atomic.release) atomic.store_explicit(<atomic.uint*>sq.ktail, tail, atomic.release)
return tail - sq.khead[0] return 1
else:
return 0
cdef int ring_select(Ring* ring, long long timeout) nogil except -1: cdef int ring_select(Ring* ring, long long timeout) nogil except -1:
cdef: cdef:
int flags = linux.IORING_ENTER_EXT_ARG int flags = linux.IORING_ENTER_EXT_ARG
bint need_enter = 0 bint need_enter = 0
unsigned submit, ready unsigned ready
unsigned wait_nr = 0 unsigned wait_nr = 0
linux.io_uring_getevents_arg arg linux.io_uring_getevents_arg arg
linux.__kernel_timespec ts linux.__kernel_timespec ts
CompletionQueue* cq = &ring.cq CompletionQueue* cq = &ring.cq
SubmissionQueue* sq = &ring.sq SubmissionQueue* sq = &ring.sq
string.memset(&arg, 0, sizeof(arg))
# Call enter if we have no CQE ready and timeout is not 0, or else we # Call enter if we have no CQE ready and timeout is not 0, or else we
# handle the ready CQEs first. # handle the ready CQEs first.
ready = atomic.load_explicit( ready = atomic.load_explicit(
@ -138,8 +141,7 @@ cdef int ring_select(Ring* ring, long long timeout) nogil except -1:
# Flush the submission queue, and only wakeup the SQ polling thread if # Flush the submission queue, and only wakeup the SQ polling thread if
# there is something for the kernel to handle. # there is something for the kernel to handle.
submit = ring_sq_flush(sq) if ring_sq_flush(sq):
if submit:
atomic.thread_fence(atomic.seq_cst) atomic.thread_fence(atomic.seq_cst)
if atomic.load_explicit( if atomic.load_explicit(
<atomic.uint*>sq.kflags, atomic.relaxed <atomic.uint*>sq.kflags, atomic.relaxed
@ -154,7 +156,7 @@ cdef int ring_select(Ring* ring, long long timeout) nogil except -1:
if libc.syscall( if libc.syscall(
libc.SYS_io_uring_enter, libc.SYS_io_uring_enter,
ring.enter_ring_fd, ring.enter_ring_fd,
submit, 0,
wait_nr, wait_nr,
flags, flags,
&arg, &arg,
@ -163,7 +165,7 @@ cdef int ring_select(Ring* ring, long long timeout) nogil except -1:
if errno.errno != errno.ETIME: if errno.errno != errno.ETIME:
with gil: with gil:
PyErr_SetFromErrno(IOError) PyErr_SetFromErrno(IOError)
return -1 return -1
ready = atomic.load_explicit( ready = atomic.load_explicit(
<atomic.uint*>cq.ktail, atomic.acquire <atomic.uint*>cq.ktail, atomic.acquire
@ -295,6 +297,7 @@ cdef int ring_sq_submit_close(
callback, callback,
) else 0 ) else 0
cdef int ring_sq_submit_sendmsg( cdef int ring_sq_submit_sendmsg(
SubmissionQueue* sq, SubmissionQueue* sq,
int fd, int fd,
@ -312,11 +315,12 @@ cdef int ring_sq_submit_sendmsg(
callback, callback,
) else 0 ) else 0
cdef int ring_sq_submit_recvmsg( cdef int ring_sq_submit_recvmsg(
SubmissionQueue* sq, SubmissionQueue* sq,
int fd, int fd,
const libc.msghdr *msg, const libc.msghdr *msg,
RingCallback* callback, RingCallback* callback,
) nogil: ) nogil:
return 1 if ring_sq_submit( return 1 if ring_sq_submit(
sq, sq,