Commit 249b5ebc authored by Jim Harris's avatar Jim Harris
Browse files

ublk: use temporary malloc buffer for kernel workaround



Some older kernels require a payload buffer to be attached
to a posted ublk io, even though the buffer isn't required
until later (either when committing a read I/O completion,
or posting a buffer in response to a NEED_DATA completion).

So instead of worrying about allocating a bunch of
valid I/O buffers for this case, just keep it simple and
use a single malloc buffer for the initial IO posting,
then immediately free that buffer.

Signed-off-by: default avatarJim Harris <james.r.harris@intel.com>
Change-Id: I59096cdb17fd6fa01adf67ffe54f2a0547a4fafb
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/17921


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
parent c6b0b77f
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -1199,15 +1199,20 @@ ublk_dev_queue_io_init(struct ublk_queue *q)
	struct ublk_io *io;
	uint32_t i;
	int rc __attribute__((unused));
	void *buf;

	/* Some older kernels require a buffer to get posted, even
	 * when NEED_GET_DATA has been specified.  So allocate a
	 * temporary buffer, only for purposes of this workaround.
	 * It never actually gets used, so we will free it immediately
	 * after all of the commands are posted.
	 */
	buf = malloc(64);

	/* submit all io commands to ublk driver */
	for (i = 0; i < q->q_depth; i++) {
		io = &q->ios[i];
		/* Some older kernels require a buffer to get posted, even
		 * when NEED_GET_DATA has been specified.  So allocate the
		 * buffers temporarily, then free them after the io_uring_submit.
		 */
		ublk_io_get_buffer(io);
		io->payload = buf;
		ublksrv_queue_io_cmd(q, io, i);
	}

@@ -1215,9 +1220,9 @@ ublk_dev_queue_io_init(struct ublk_queue *q)
	assert(rc == (int)q->q_depth);
	for (i = 0; i < q->q_depth; i++) {
		io = &q->ios[i];
		assert(io->payload != NULL);
		ublk_io_put_buffer(io);
		io->payload = NULL;
	}
	free(buf);
}

static void