On 6/9/22 17:33, Hao Xu wrote:
On 6/9/22 15:53, Hao Xu wrote:
Hi all,
I haven't done tests to demonstrate it. It is for partial io case, we
don't consume/release the buffer before arm_poll in ring-mapped mode.
But seems we should? Otherwise ring head isn't moved and other requests
may take that buffer. What do I miss?
Regards,
Hao
something like this:
forgot something in previous diff
diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c
index d2b2b4728381..9ff8d14277ff 100644
--- a/io_uring/kbuf.c
+++ b/io_uring/kbuf.c
@@ -49,8 +49,15 @@ void __io_kbuf_recycle(struct io_kiocb *req, unsigned
issue_flags)
*/
if (req->flags & REQ_F_BUFFER_RING) {
if (req->buf_list) {
- req->buf_index = req->buf_list->bgid;
- req->flags &= ~REQ_F_BUFFER_RING;
+ if (req->flags & REQ_F_PARTIAL_IO) {
+ io_ring_submit_lock(ctx, issue_flags);
+ req->buf_list->head++;
+ io_ring_submit_unlock(ctx, issue_flags);
+ req->buf_list = NULL;
+ } else {
+ req->buf_index = req->buf_list->bgid;
+ req->flags &= ~REQ_F_BUFFER_RING;
+ }
}
return;
}
diff --git a/io_uring/kbuf.h b/io_uring/kbuf.h
index b58d9d20c97e..9ecb175e60a9 100644
--- a/io_uring/kbuf.h
+++ b/io_uring/kbuf.h
@@ -58,8 +58,14 @@ static inline void io_kbuf_recycle(struct io_kiocb
*req, unsigned issue_flags)
{
if (!(req->flags & (REQ_F_BUFFER_SELECTED|REQ_F_BUFFER_RING)))
return;
- /* don't recycle if we already did IO to this buffer */
- if (req->flags & REQ_F_PARTIAL_IO)
+ /*
+ * For legacy provided buffer mode, don't recycle if we already did
+ * IO to this buffer. For ring-mapped provided buffer mode, we
should
+ * increment ring->head to explicitly monopolize the buffer to avoid
+ * multiple use.
+ */
+ if ((req->flags & REQ_F_BUFFER_SELECTED) &&
+ (req->flags & REQ_F_PARTIAL_IO))
return;
__io_kbuf_recycle(req, issue_flags);
}