unsigned i, tail, old_head;
struct io_uring_params *p = &config.p;
struct io_rings_layout *rl = &config.layout;
+ u32 *o_sq_array, *n_sq_array = NULL;
int ret;
memset(&config, 0, sizeof(config));
ctx->rings = NULL;
o.sq_sqes = ctx->sq_sqes;
ctx->sq_sqes = NULL;
+ o_sq_array = ctx->sq_array;
+ if (!(ctx->flags & IORING_SETUP_NO_SQARRAY))
+ n_sq_array = (u32 *)((char *)n.rings + rl->sq_array_offset);
/*
* Now copy SQ and CQ entries, if any. If either of the destination
if (tail - old_head > p->sq_entries)
goto overflow;
for (i = old_head; i < tail; i++) {
- unsigned index, dst_mask, src_mask;
+ unsigned int dst, src;
size_t sq_size;
- index = i;
+ dst = i & (p->sq_entries - 1);
+ src = i & (ctx->sq_entries - 1);
+ if (n_sq_array) {
+ src = READ_ONCE(o_sq_array[src]);
+ if (unlikely(src >= ctx->sq_entries)) {
+ WRITE_ONCE(n_sq_array[dst], UINT_MAX);
+ continue;
+ }
+ WRITE_ONCE(n_sq_array[dst], dst);
+ }
+
sq_size = sizeof(struct io_uring_sqe);
- src_mask = ctx->sq_entries - 1;
- dst_mask = p->sq_entries - 1;
if (ctx->flags & IORING_SETUP_SQE128) {
- index <<= 1;
+ dst <<= 1;
+ src <<= 1;
sq_size <<= 1;
- src_mask = (ctx->sq_entries << 1) - 1;
- dst_mask = (p->sq_entries << 1) - 1;
}
- memcpy(&n.sq_sqes[index & dst_mask], &o.sq_sqes[index & src_mask], sq_size);
+ memcpy(&n.sq_sqes[dst], &o.sq_sqes[src], sq_size);
}
WRITE_ONCE(n.rings->sq.head, old_head);
WRITE_ONCE(n.rings->sq.tail, tail);
WRITE_ONCE(n.rings->cq_overflow, READ_ONCE(o.rings->cq_overflow));
/* all done, store old pointers and assign new ones */
- if (!(ctx->flags & IORING_SETUP_NO_SQARRAY))
- ctx->sq_array = (u32 *)((char *)n.rings + rl->sq_array_offset);
+ if (n_sq_array)
+ ctx->sq_array = n_sq_array;
ctx->sq_entries = p->sq_entries;
ctx->cq_entries = p->cq_entries;