Commit dbbc8e1d authored by Richael Zhuang's avatar Richael Zhuang Committed by Tomasz Zawadzki
Browse files

ublk: fix segmentfault when running fio test on ublk device



fio test fails with IO error log on some cases, and spdk_tgt ends
in segmentfault.

The cause is the content in io descriptor may have been updated
by next io request when calling ublk_io_put_buffer. The io_size
that ublk_io_get_buffer and ublk_io_put_buffer caculate may be
different if caculated from io->iod->nr_sectors. Then it may get
the buf from the small buf pool and return to the large buf pool.

So record the io size when getting the buf and use this size when
putting the buf.

Change-Id: I44e4f85f180decd79f806cd5e3a60573e974056a
Signed-off-by: default avatarRichael Zhuang <richael.zhuang@arm.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/19713


Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 74f2d4f7
Loading
Loading
Loading
Loading
+5 −8
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ struct ublk_io {
	bool			need_data;
	bool			user_copy;
	uint16_t		tag;
	uint32_t		payload_size;
	uint64_t		payload_size;
	uint32_t		cmd_op;
	int32_t			result;
	struct spdk_bdev_desc	*bdev_desc;
@@ -1055,12 +1055,12 @@ static void
ublk_io_get_buffer(struct ublk_io *io, struct spdk_iobuf_channel *iobuf_ch,
		   ublk_get_buf_cb get_buf_cb)
{
	uint64_t io_size;
	void *buf;

	io_size = io->iod->nr_sectors * (1ULL << LINUX_SECTOR_SHIFT);
	io->payload_size = io->iod->nr_sectors * (1ULL << LINUX_SECTOR_SHIFT);
	io->get_buf_cb = get_buf_cb;
	buf = spdk_iobuf_get(iobuf_ch, io_size, &io->iobuf, ublk_io_get_buffer_cb);
	buf = spdk_iobuf_get(iobuf_ch, io->payload_size, &io->iobuf, ublk_io_get_buffer_cb);

	if (buf != NULL) {
		ublk_io_get_buffer_cb(&io->iobuf, buf);
	}
@@ -1069,11 +1069,8 @@ ublk_io_get_buffer(struct ublk_io *io, struct spdk_iobuf_channel *iobuf_ch,
static void
ublk_io_put_buffer(struct ublk_io *io, struct spdk_iobuf_channel *iobuf_ch)
{
	uint64_t io_size;

	if (io->payload) {
		io_size = io->iod->nr_sectors * (1ULL << LINUX_SECTOR_SHIFT);
		spdk_iobuf_put(iobuf_ch, io->mpool_entry, io_size);
		spdk_iobuf_put(iobuf_ch, io->mpool_entry, io->payload_size);
		io->mpool_entry = NULL;
		io->payload = NULL;
	}