static void long_seq_test_free_end_io_fn(struct request *rq, int err)
{
	struct test_request *test_rq;
	struct test_data *ptd = test_get_test_data();

	if (rq)
		test_rq = (struct test_request *)rq->elv.priv[0];
	else {
		test_pr_err("%s: error: NULL request", __func__);
		return;
	}

	BUG_ON(!test_rq);

	spin_lock_irq(&ptd->lock);
	ptd->dispatched_count--;
	list_del_init(&test_rq->queuelist);
	__blk_put_request(ptd->req_q, test_rq->rq);
	spin_unlock_irq(&ptd->lock);

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

	test_pr_err("%s: request %d completed, err=%d",
	       __func__, test_rq->req_id, err);

	check_test_completion();

}
示例#2
0
static int ufs_test_debugfs_init(void)
{
	struct dentry *utils_root, *tests_root;

	utils_root = test_iosched_get_debugfs_utils_root();
	tests_root = test_iosched_get_debugfs_tests_root();

	if (!utils_root || !tests_root) {
		test_pr_err("%s: Failed to create debugfs root.", __func__);
		return -EINVAL;
	}

	utd->debug.random_test_seed = debugfs_create_u32("random_test_seed",
			S_IRUGO | S_IWUGO, utils_root, &utd->random_test_seed);

	if (!utd->debug.random_test_seed) {
		test_pr_err("%s: Could not create debugfs random_test_seed.",
				__func__);
		return -ENOMEM;
	}

	utd->debug.write_read_test = debugfs_create_file("write_read_test",
					S_IRUGO | S_IWUGO, tests_root,
					NULL, &write_read_test_ops);

	if (!utd->debug.write_read_test) {
		debugfs_remove(utd->debug.random_test_seed);
		test_pr_err("%s: Could not create debugfs write_read_test.",
				__func__);
		return -ENOMEM;
	}

	return 0;
}
static int ufs_test_run_write_read_test(struct test_data *td)
{
	int ret = 0;
	unsigned int start_sec;
	unsigned int num_bios;
	struct request_queue *q = td->req_q;


	start_sec = td->start_sector + sizeof(int) * BIO_U32_SIZE
			* td->num_of_write_bios;
	if (utd->random_test_seed != 0)
		ufs_test_pseudo_rnd_size(&utd->random_test_seed, &num_bios);
	else
		num_bios = DEFAULT_NUM_OF_BIOS;

	/* Adding a write request */
	test_pr_info(
		"%s: Adding a write request with %d bios to Q, req_id=%d"
			, __func__, num_bios, td->wr_rd_next_req_id);

	utd->write_completed = false;
	ret = test_iosched_add_wr_rd_test_req(0, WRITE, start_sec,
					num_bios, TEST_PATTERN_5A,
					ufs_test_write_read_test_end_io_fn);

	if (ret) {
		test_pr_err("%s: failed to add a write request", __func__);
		return ret;
	}

	/* waiting for the write request to finish */
	blk_run_queue(q);
	wait_event(utd->wait_q, utd->write_completed);

	/* Adding a read request*/
	test_pr_info("%s: Adding a read request to Q", __func__);

	ret = test_iosched_add_wr_rd_test_req(0, READ, start_sec,
			num_bios, TEST_PATTERN_5A, NULL);

	if (ret) {
		test_pr_err("%s: failed to add a read request", __func__);
		return ret;
	}

	blk_run_queue(q);
	return ret;
}
static int run_long_seq_test(struct test_data *td)
{
	int ret = 0;
	int direction;
	static unsigned int inserted_requests;

	BUG_ON(!td);
	td->test_count = 0;
	utd->completed_req_count = 0;
	inserted_requests = 0;

	if (td->test_info.testcase == TEST_LONG_SEQUENTIAL_READ)
		direction = READ;
	else
		direction = WRITE;

	test_pr_info("%s: Adding %d requests, first req_id=%d",
		     __func__, LONG_SEQ_TEST_NUM_REQS,
		     td->wr_rd_next_req_id);

	do {
		/*
		* since our requests come from a pool containing 128
		* requests, we don't want to exhaust this quantity,
		* therefore we add up to QUEUE_MAX_REQUESTS (which
		* includes a safety margin) and then call the mmc layer
		* to fetch them
		*/
		if (td->test_count >= QUEUE_MAX_REQUESTS) {
			blk_run_queue(td->req_q);
			continue;
		}

		ret = test_iosched_add_wr_rd_test_req(0, direction,
			td->start_sector, TEST_MAX_BIOS_PER_REQ,
			TEST_PATTERN_5A,
			long_seq_test_free_end_io_fn);
		if (ret) {
			test_pr_err("%s: failed to create request" , __func__);
			break;
		}
		inserted_requests++;
		td->test_info.test_byte_count +=
			(TEST_MAX_BIOS_PER_REQ * sizeof(unsigned int) *
			BIO_U32_SIZE);

	} while (inserted_requests < LONG_SEQ_TEST_NUM_REQS);

	/* in this case the queue will not run in the above loop */
	if (LONG_SEQ_TEST_NUM_REQS < QUEUE_MAX_REQUESTS)
		blk_run_queue(td->req_q);

	return ret;
}
示例#5
0
static char *ufs_test_get_test_case_str(struct test_data *td)
{
	if (!td) {
		test_pr_err("%s: NULL td", __func__);
		return NULL;
	}

	switch (td->test_info.testcase) {
	case UFS_TEST_WRITE_READ_TEST:
		return "UFS write read test";
		break;
	default:
		return "Unknown test";
	}
}
示例#6
0
int __init ufs_test_init(void)
{
	utd = kzalloc(sizeof(struct ufs_test_data), GFP_KERNEL);
	if (!utd) {
		test_pr_err("%s: failed to allocate ufs_test_data", __func__);
		return -ENODEV;
	}

	init_waitqueue_head(&utd->wait_q);
	utd->bdt.init_fn = ufs_test_probe;
	utd->bdt.exit_fn = ufs_test_remove;
	INIT_LIST_HEAD(&utd->bdt.list);
	test_iosched_register(&utd->bdt);

	return 0;
}
static int run_long_seq_test(struct test_data *td)
{
	int ret = 0;
	int direction;
	static unsigned int inserted_requests;

	BUG_ON(!td);
	td->test_count = 0;
	utd->completed_req_count = 0;
	inserted_requests = 0;

	if (td->test_info.testcase == TEST_LONG_SEQUENTIAL_READ)
		direction = READ;
	else
		direction = WRITE;

	test_pr_info("%s: Adding %d requests, first req_id=%d",
		     __func__, LONG_SEQ_TEST_NUM_REQS,
		     td->wr_rd_next_req_id);

	do {
		if (td->test_count >= QUEUE_MAX_REQUESTS) {
			blk_run_queue(td->req_q);
			continue;
		}

		ret = test_iosched_add_wr_rd_test_req(0, direction,
			td->start_sector, TEST_MAX_BIOS_PER_REQ,
			TEST_PATTERN_5A,
			long_seq_test_free_end_io_fn);
		if (ret) {
			test_pr_err("%s: failed to create request" , __func__);
			break;
		}
		inserted_requests++;
		td->test_info.test_byte_count +=
			(TEST_MAX_BIOS_PER_REQ * sizeof(unsigned int) *
			BIO_U32_SIZE);

	} while (inserted_requests < LONG_SEQ_TEST_NUM_REQS);

	
	if (LONG_SEQ_TEST_NUM_REQS < QUEUE_MAX_REQUESTS)
		blk_run_queue(td->req_q);

	return ret;
}
示例#8
0
static ssize_t ufs_test_write_read_test_write_cb(struct file *file,
					const char __user *buf,
					size_t count, loff_t *ppos)
{
	int ret = 0;
	int i;
	int number;

	sscanf(buf, "%d", &number);

	if (number <= 0)
		number = 1;

	test_pr_info("%s:the test will run for %d iterations.",
			__func__, number);
	memset(&utd->test_info, 0, sizeof(struct test_info));

	/* Initializing test */
	utd->test_info.data = utd;
	utd->test_info.get_test_case_str_fn = ufs_test_get_test_case_str;
	utd->test_info.testcase = UFS_TEST_WRITE_READ_TEST;
	utd->test_info.get_rq_disk_fn = ufs_test_get_rq_disk;
	utd->test_info.run_test_fn = ufs_test_run_write_read_test;

	/* Running the test multiple times */
	for (i = 0; i < number; ++i) {
		ret = test_iosched_start_test(&utd->test_info);
		if (ret) {
			test_pr_err("%s: Test failed.", __func__);
			return ret;
		}
	}

	test_pr_info("%s: Completed all the ufs test iterations.", __func__);

	return count;
}
static int ufs_test_debugfs_init(void)
{
	struct dentry *utils_root, *tests_root;
	int ret = 0;

	utils_root = test_iosched_get_debugfs_utils_root();
	tests_root = test_iosched_get_debugfs_tests_root();

	if (!utils_root || !tests_root) {
		test_pr_err("%s: Failed to create debugfs root.", __func__);
		ret = -EINVAL;
		goto exit;
	}

	utd->debug.random_test_seed = debugfs_create_u32("random_test_seed",
			S_IRUGO | S_IWUGO, utils_root, &utd->random_test_seed);

	if (!utd->debug.random_test_seed) {
		test_pr_err("%s: Could not create debugfs random_test_seed.",
				__func__);
		ret = -ENOMEM;
		goto exit;
	}

	utd->debug.write_read_test = debugfs_create_file("ufs_write_read_test",
					S_IRUGO | S_IWUGO, tests_root,
					NULL, &write_read_test_ops);

	if (!utd->debug.write_read_test) {
		ret = -ENOMEM;
		goto exit_err;
	}

	utd->debug.long_sequential_read_test = debugfs_create_file(
					"ufs_long_sequential_read_test",
					S_IRUGO | S_IWUGO,
					tests_root,
					NULL,
					&long_sequential_read_test_ops);

	if (!utd->debug.long_sequential_read_test) {
		ret = -ENOMEM;
		goto exit_err;
	}

	utd->debug.long_sequential_write_test = debugfs_create_file(
					"ufs_long_sequential_write_test",
					S_IRUGO | S_IWUGO,
					tests_root,
					NULL,
					&long_sequential_write_test_ops);

	if (!utd->debug.long_sequential_write_test) {
		ret = -ENOMEM;
		goto exit_err;
	}

	goto exit;

exit_err:
	debugfs_remove_recursive(tests_root);
exit:
	return ret;
}