Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'io_uring-6.15-20250515' of git://git.kernel.dk/linux

Pull io_uring fixes from Jens Axboe:

- Fix a regression with highmem and mapping of regions, where
the coalescing code assumes any page is directly mapped

- Fix an issue with HYBRID_IOPOLL and passthrough commands,
where the timer wasn't always setup correctly

- Fix an issue with fdinfo not correctly locking around reading
the rings, which can be an issue if the ring is being resized
at the same time

* tag 'io_uring-6.15-20250515' of git://git.kernel.dk/linux:
io_uring/fdinfo: grab ctx->uring_lock around io_uring_show_fdinfo()
io_uring/memmap: don't use page_address() on a highmem page
io_uring/uring_cmd: fix hybrid polling initialization issue

+31 -24
+25 -23
io_uring/fdinfo.c
··· 86 86 } 87 87 #endif 88 88 89 - /* 90 - * Caller holds a reference to the file already, we don't need to do 91 - * anything else to get an extra reference. 92 - */ 93 - __cold void io_uring_show_fdinfo(struct seq_file *m, struct file *file) 89 + static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m) 94 90 { 95 - struct io_ring_ctx *ctx = file->private_data; 96 91 struct io_overflow_cqe *ocqe; 97 92 struct io_rings *r = ctx->rings; 98 93 struct rusage sq_usage; ··· 101 106 unsigned int sq_entries, cq_entries; 102 107 int sq_pid = -1, sq_cpu = -1; 103 108 u64 sq_total_time = 0, sq_work_time = 0; 104 - bool has_lock; 105 109 unsigned int i; 106 110 107 111 if (ctx->flags & IORING_SETUP_CQE32) ··· 170 176 seq_printf(m, "\n"); 171 177 } 172 178 173 - /* 174 - * Avoid ABBA deadlock between the seq lock and the io_uring mutex, 175 - * since fdinfo case grabs it in the opposite direction of normal use 176 - * cases. If we fail to get the lock, we just don't iterate any 177 - * structures that could be going away outside the io_uring mutex. 178 - */ 179 - has_lock = mutex_trylock(&ctx->uring_lock); 180 - 181 - if (has_lock && (ctx->flags & IORING_SETUP_SQPOLL)) { 179 + if (ctx->flags & IORING_SETUP_SQPOLL) { 182 180 struct io_sq_data *sq = ctx->sq_data; 183 181 184 182 /* ··· 192 206 seq_printf(m, "SqTotalTime:\t%llu\n", sq_total_time); 193 207 seq_printf(m, "SqWorkTime:\t%llu\n", sq_work_time); 194 208 seq_printf(m, "UserFiles:\t%u\n", ctx->file_table.data.nr); 195 - for (i = 0; has_lock && i < ctx->file_table.data.nr; i++) { 209 + for (i = 0; i < ctx->file_table.data.nr; i++) { 196 210 struct file *f = NULL; 197 211 198 212 if (ctx->file_table.data.nodes[i]) ··· 204 218 } 205 219 } 206 220 seq_printf(m, "UserBufs:\t%u\n", ctx->buf_table.nr); 207 - for (i = 0; has_lock && i < ctx->buf_table.nr; i++) { 221 + for (i = 0; i < ctx->buf_table.nr; i++) { 208 222 struct io_mapped_ubuf *buf = NULL; 209 223 210 224 if (ctx->buf_table.nodes[i]) ··· 214 228 else 215 229 seq_printf(m, "%5u: <none>\n", i); 216 230 } 217 - if (has_lock && !xa_empty(&ctx->personalities)) { 231 + if (!xa_empty(&ctx->personalities)) { 218 232 unsigned long index; 219 233 const struct cred *cred; 220 234 ··· 224 238 } 225 239 226 240 seq_puts(m, "PollList:\n"); 227 - for (i = 0; has_lock && i < (1U << ctx->cancel_table.hash_bits); i++) { 241 + for (i = 0; i < (1U << ctx->cancel_table.hash_bits); i++) { 228 242 struct io_hash_bucket *hb = &ctx->cancel_table.hbs[i]; 229 243 struct io_kiocb *req; 230 244 ··· 232 246 seq_printf(m, " op=%d, task_works=%d\n", req->opcode, 233 247 task_work_pending(req->tctx->task)); 234 248 } 235 - 236 - if (has_lock) 237 - mutex_unlock(&ctx->uring_lock); 238 249 239 250 seq_puts(m, "CqOverflowList:\n"); 240 251 spin_lock(&ctx->completion_lock); ··· 244 261 } 245 262 spin_unlock(&ctx->completion_lock); 246 263 napi_show_fdinfo(ctx, m); 264 + } 265 + 266 + /* 267 + * Caller holds a reference to the file already, we don't need to do 268 + * anything else to get an extra reference. 269 + */ 270 + __cold void io_uring_show_fdinfo(struct seq_file *m, struct file *file) 271 + { 272 + struct io_ring_ctx *ctx = file->private_data; 273 + 274 + /* 275 + * Avoid ABBA deadlock between the seq lock and the io_uring mutex, 276 + * since fdinfo case grabs it in the opposite direction of normal use 277 + * cases. 278 + */ 279 + if (mutex_trylock(&ctx->uring_lock)) { 280 + __io_uring_show_fdinfo(ctx, m); 281 + mutex_unlock(&ctx->uring_lock); 282 + } 247 283 } 248 284 #endif
+1 -1
io_uring/memmap.c
··· 116 116 void *ptr; 117 117 118 118 if (io_check_coalesce_buffer(mr->pages, mr->nr_pages, &ifd)) { 119 - if (ifd.nr_folios == 1) { 119 + if (ifd.nr_folios == 1 && !PageHighMem(mr->pages[0])) { 120 120 mr->ptr = page_address(mr->pages[0]); 121 121 return 0; 122 122 }
+5
io_uring/uring_cmd.c
··· 254 254 return -EOPNOTSUPP; 255 255 issue_flags |= IO_URING_F_IOPOLL; 256 256 req->iopoll_completed = 0; 257 + if (ctx->flags & IORING_SETUP_HYBRID_IOPOLL) { 258 + /* make sure every req only blocks once */ 259 + req->flags &= ~REQ_F_IOPOLL_STATE; 260 + req->iopoll_start = ktime_get_ns(); 261 + } 257 262 } 258 263 259 264 ret = file->f_op->uring_cmd(ioucmd, issue_flags);