Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9195406e authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "block: test-iosched: fix bio allocation for test requests"

parents 74c42670 8aeb623c
Loading
Loading
Loading
Loading
+52 −54
Original line number Diff line number Diff line
@@ -112,6 +112,21 @@ static void end_test_bio(struct bio *bio, int err)
	bio_put(bio);
}

void test_iosched_free_test_req_data_buffer(struct test_request *test_rq)
{
	int i;

	if (!test_rq)
		return;

	for (i = 0; i < BLK_MAX_SEGMENTS; i++)
		if (test_rq->bios_buffer[i]) {
			free_page((unsigned long)test_rq->bios_buffer[i]);
			test_rq->bios_buffer[i] = NULL;
		}
}
EXPORT_SYMBOL(test_iosched_free_test_req_data_buffer);

/*
 * A callback to be called per request completion.
 * the request memory is not freed here, will be freed later after the test
@@ -281,17 +296,14 @@ struct test_request *test_iosched_create_test_req(
{
	struct request *rq;
	struct test_request *test_rq;
	int rw_flags, buf_size;
	int ret = 0, i;
	unsigned int *bio_ptr = NULL;
	struct bio *bio = NULL;
	int i;
	int ret;

	if (!tios)
		return NULL;

	rw_flags = direction;

	rq = blk_get_request(tios->req_q, rw_flags, GFP_KERNEL);
	rq = blk_get_request(tios->req_q, direction, GFP_KERNEL);
	if (!rq) {
		pr_err("%s: Failed to allocate a request", __func__);
		return NULL;
@@ -300,35 +312,29 @@ struct test_request *test_iosched_create_test_req(
	test_rq = kzalloc(sizeof(struct test_request), GFP_KERNEL);
	if (!test_rq) {
		pr_err("%s: Failed to allocate test request", __func__);
		blk_put_request(rq);
		return NULL;
	}

	buf_size = TEST_BIO_SIZE * num_bios;
	test_rq->bios_buffer = kzalloc(buf_size, GFP_KERNEL);
	if (!test_rq->bios_buffer) {
		pr_err("%s: Failed to allocate the data buf", __func__);
		goto err;
	}
	test_rq->buf_size = buf_size;

	if (direction == WRITE)
		fill_buf_with_pattern(test_rq->bios_buffer,
						   buf_size, pattern);
	test_rq->buf_size = TEST_BIO_SIZE * num_bios;
	test_rq->wr_rd_data_pattern = pattern;

	bio_ptr = test_rq->bios_buffer;
	for (i = 0; i < num_bios; ++i) {
		ret = blk_rq_map_kern(tios->req_q, rq,
				      (void *)bio_ptr,
				      sizeof(unsigned int)*BIO_U32_SIZE,
				      GFP_KERNEL);
	for (i = 0; i < num_bios; i++) {
		test_rq->bios_buffer[i] = (void *)get_zeroed_page(GFP_KERNEL);
		if (!test_rq->bios_buffer[i]) {
			pr_err("%s: failed to kmap page for bio #%d/%d\n",
				__func__, i, num_bios);
			goto free_bios;
		}
		ret = blk_rq_map_kern(tios->req_q, rq, test_rq->bios_buffer[i],
			TEST_BIO_SIZE, GFP_KERNEL);
		if (ret) {
			pr_err("%s: blk_rq_map_kern returned error %d",
				__func__, ret);
			goto err;
			goto free_bios;
		}
		bio_ptr += BIO_U32_SIZE;
		if (direction == WRITE)
			fill_buf_with_pattern(test_rq->bios_buffer[i],
				TEST_BIO_SIZE, pattern);
	}

	if (end_req_io)
@@ -355,18 +361,16 @@ struct test_request *test_iosched_create_test_req(
	test_rq->req_result = -EINVAL;
	test_rq->rq = rq;
	if (tios->test_info.get_rq_disk_fn)
		test_rq->rq->rq_disk =
			tios->test_info.get_rq_disk_fn(tios);
		test_rq->rq->rq_disk = tios->test_info.get_rq_disk_fn(tios);
	test_rq->is_err_expected = is_err_expcted;
	rq->elv.priv[0] = (void *)test_rq;

	pr_debug("%s: created test request %d, buf_size=%d",
			__func__, test_rq->req_id, buf_size);

	return test_rq;

free_bios:
	test_iosched_free_test_req_data_buffer(test_rq);
	kfree(test_rq);
err:
	blk_put_request(rq);
	kfree(test_rq->bios_buffer);
	return NULL;
}
EXPORT_SYMBOL(test_iosched_create_test_req);
@@ -434,8 +438,9 @@ static char *get_test_case_str(struct test_iosched *tios)
 */
int compare_buffer_to_pattern(struct test_request *test_rq)
{
	int i = 0;
	int num_of_dwords = test_rq->buf_size/sizeof(int);
	int i;
	int j;
	unsigned int *buf;

	/* num_bytes should be aligned to sizeof(int) */
	BUG_ON((test_rq->buf_size % sizeof(int)) != 0);
@@ -444,26 +449,19 @@ int compare_buffer_to_pattern(struct test_request *test_rq)
	if (test_rq->wr_rd_data_pattern == TEST_NO_PATTERN)
		return 0;

	if (test_rq->wr_rd_data_pattern == TEST_PATTERN_SEQUENTIAL) {
		for (i = 0; i < num_of_dwords; i++) {
			if (test_rq->bios_buffer[i] != i) {
				pr_err(
					"%s: wrong pattern 0x%x in index %d",
					__func__, test_rq->bios_buffer[i], i);
	for (i = 0; i < test_rq->buf_size / TEST_BIO_SIZE; i++) {
		buf = test_rq->bios_buffer[i];
		for (j = 0; j < TEST_BIO_SIZE / sizeof(int); j++)
			if ((test_rq->wr_rd_data_pattern ==
				TEST_PATTERN_SEQUENTIAL && buf[j] != j) ||
				(test_rq->wr_rd_data_pattern !=
				TEST_PATTERN_SEQUENTIAL &&
				buf[j] != test_rq->wr_rd_data_pattern)) {
				pr_err("%s: wrong pattern 0x%x in index %d",
					__func__, buf[j], j);
				return -EINVAL;
			}
	}
	} else {
		for (i = 0; i < num_of_dwords; i++) {
			if (test_rq->bios_buffer[i] !=
			    test_rq->wr_rd_data_pattern) {
				pr_err(
					"%s: wrong pattern 0x%x in index %d",
					__func__, test_rq->bios_buffer[i], i);
				return -EINVAL;
			}
		}
	}

	return 0;
}
@@ -595,7 +593,7 @@ static void free_test_queue(struct list_head *test_queue)
			}
		}
		blk_put_request(test_rq->rq);
		kfree(test_rq->bios_buffer);
		test_iosched_free_test_req_data_buffer(test_rq);
		kfree(test_rq);
	}
}
+2 −2
Original line number Diff line number Diff line
@@ -2102,7 +2102,7 @@ static void new_req_free_end_io_fn(struct request *rq, int err)
	spin_unlock_irq(&tios->lock);

	__blk_put_request(tios->req_q, test_rq->rq);
	kfree(test_rq->bios_buffer);
	test_iosched_free_test_req_data_buffer(test_rq);
	kfree(test_rq);
	mbtd->completed_req_count++;
}
@@ -2857,7 +2857,7 @@ static void long_seq_write_free_end_io_fn(struct request *rq, int err)
	__blk_put_request(tios->req_q, test_rq->rq);
	spin_unlock_irq(&tios->lock);

	kfree(test_rq->bios_buffer);
	test_iosched_free_test_req_data_buffer(test_rq);
	kfree(test_rq);
	mbtd->completed_req_count++;

+2 −2
Original line number Diff line number Diff line
@@ -678,7 +678,7 @@ static void scenario_free_end_io_fn(struct request *rq, int err)
	__blk_put_request(test_iosched->req_q, test_rq->rq);
	spin_unlock_irq(&test_iosched->lock);

	kfree(test_rq->bios_buffer);
	test_iosched_free_test_req_data_buffer(test_rq);
	kfree(test_rq);

	if (err)
@@ -972,7 +972,7 @@ static void long_test_free_end_io_fn(struct request *rq, int err)
		return;
	}

	kfree(test_rq->bios_buffer);
	test_iosched_free_test_req_data_buffer(test_rq);
	kfree(test_rq);
	utd->completed_req_count++;

+4 −2
Original line number Diff line number Diff line
@@ -92,7 +92,7 @@ struct test_debug {
/**
 * struct test_request - defines a test request
 * @queuelist:		The test requests list
 * @bios_buffer:	Write/read requests data buffer
 * @bios_buffer:	Write/read requests data buffer, one page per bio
 * @buf_size:		Write/read requests data buffer size (in
 *			bytes)
 * @rq:			A block request, to be dispatched
@@ -110,7 +110,7 @@ struct test_debug {
 */
struct test_request {
	struct list_head queuelist;
	unsigned int *bios_buffer;
	void *bios_buffer[BLK_MAX_SEGMENTS];
	int buf_size;
	struct request *rq;
	bool req_completed;
@@ -250,6 +250,8 @@ extern struct test_request *test_iosched_create_test_req(struct test_iosched *,
	int is_err_expcted, int direction, int start_sec, int num_bios,
	int pattern, rq_end_io_fn *end_req_io);

extern void test_iosched_free_test_req_data_buffer(struct test_request *);

extern void test_iosched_set_test_result(struct test_iosched*, int test_result);

extern void test_iosched_set_ignore_round(struct test_iosched *,