mmc: do not pack random requests

Packed commands causes higher latency since the completion of each
request is sent to the upper layer upon completion of the complete
packed request.
The benefit from this feature is card dependent. Some of the card
vendors do not have any benefit from using packed commands for random
requests. In case there is no benefit in random requests packing,
it is better to disable the packing to prevent this high latency.
This patch also add the new stop packing reason to the write packing
statistics.

Change-Id: I141887dcef2ceee14848634cc27c3c85f8edc7a5
Signed-off-by: Maya Erez <merez@codeaurora.org>
[merez@codeaurora.org: fix conflicts due to removal of BKOPS]
Signed-off-by: Maya Erez <merez@codeaurora.org>
This commit is contained in:
Maya Erez 2014-12-04 15:13:59 +02:00 committed by Subhash Jadavani
parent 62649ebdb6
commit 23bf711121
4 changed files with 81 additions and 0 deletions

View file

@ -130,6 +130,7 @@ struct mmc_blk_data {
struct device_attribute force_ro;
struct device_attribute power_ro_lock;
struct device_attribute num_wr_reqs_to_start_packing;
struct device_attribute no_pack_for_random;
int area_type;
};
@ -348,6 +349,55 @@ exit:
return ret;
}
static ssize_t
no_pack_for_random_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
int ret;
ret = snprintf(buf, PAGE_SIZE, "%d\n", md->queue.no_pack_for_random);
mmc_blk_put(md);
return ret;
}
static ssize_t
no_pack_for_random_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int value;
struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
struct mmc_card *card = md->queue.card;
int ret = count;
if (!card) {
ret = -EINVAL;
goto exit;
}
sscanf(buf, "%d", &value);
if (value < 0) {
pr_err("%s: value %d is not valid. old value remains = %d",
mmc_hostname(card->host), value,
md->queue.no_pack_for_random);
ret = -EINVAL;
goto exit;
}
md->queue.no_pack_for_random = (value > 0) ? true : false;
pr_debug("%s: no_pack_for_random: new value = %d",
mmc_hostname(card->host),
md->queue.no_pack_for_random);
exit:
mmc_blk_put(md);
return ret;
}
static int mmc_blk_open(struct block_device *bdev, fmode_t mode)
{
struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk);
@ -1870,6 +1920,15 @@ static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req)
break;
}
if (mq->no_pack_for_random) {
if ((blk_rq_pos(cur) + blk_rq_sectors(cur)) !=
blk_rq_pos(next)) {
MMC_BLK_UPDATE_STOP_REASON(stats, RANDOM);
put_back = 1;
break;
}
}
if (rq_data_dir(next) == WRITE)
mq->num_of_potential_packed_wr_reqs++;
list_add_tail(&next->queuelist, &mqrq->packed->list);
@ -2653,8 +2712,21 @@ static int mmc_add_disk(struct mmc_blk_data *md)
if (ret)
goto num_wr_reqs_to_start_packing_fail;
md->no_pack_for_random.show = no_pack_for_random_show;
md->no_pack_for_random.store = no_pack_for_random_store;
sysfs_attr_init(&md->no_pack_for_random.attr);
md->no_pack_for_random.attr.name = "no_pack_for_random";
md->no_pack_for_random.attr.mode = S_IRUGO | S_IWUSR;
ret = device_create_file(disk_to_dev(md->disk),
&md->no_pack_for_random);
if (ret)
goto no_pack_for_random_fails;
return ret;
no_pack_for_random_fails:
device_remove_file(disk_to_dev(md->disk),
&md->num_wr_reqs_to_start_packing);
num_wr_reqs_to_start_packing_fail:
device_remove_file(disk_to_dev(md->disk), &md->power_ro_lock);
power_ro_lock_fail:

View file

@ -61,6 +61,7 @@ struct mmc_queue {
bool wr_packing_enabled;
int num_of_potential_packed_wr_reqs;
int num_wr_reqs_to_start_packing;
bool no_pack_for_random;
int (*err_check_fn) (struct mmc_card *, struct mmc_async_req *);
void (*packed_test_fn) (struct request_queue *, struct mmc_queue_req *);
};

View file

@ -524,6 +524,13 @@ static ssize_t mmc_wr_pack_stats_read(struct file *filp, char __user *ubuf,
pack_stats->pack_stop_reason[LARGE_SEC_ALIGN]);
strlcat(ubuf, temp_buf, cnt);
}
if (pack_stats->pack_stop_reason[RANDOM]) {
snprintf(temp_buf, TEMP_BUF_SIZE,
"%s: %d times: random request\n",
mmc_hostname(card->host),
pack_stats->pack_stop_reason[RANDOM]);
strlcat(ubuf, temp_buf, cnt);
}
spin_unlock(&pack_stats->lock);

View file

@ -227,6 +227,7 @@ enum mmc_packed_stop_reasons {
REL_WRITE,
THRESHOLD,
LARGE_SEC_ALIGN,
RANDOM,
MAX_REASONS,
};