Skip to content

Commit f7b6fc3

Browse files
vwaxUlf Hansson
authored andcommitted
mmc: core: Support zeroout using TRIM for eMMC
If an eMMC card supports TRIM and indicates that it erases to zeros, we can use it to support hardware offloading of REQ_OP_WRITE_ZEROES, so let's add support for this. Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com> Reviewed-by: Avri Altman <Avri.Altman@wdc.com> Link: https://lore.kernel.org/r/20220429152118.3617303-1-vincent.whitchurch@axis.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent 0c9ee5b commit f7b6fc3

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

drivers/mmc/core/block.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ struct mmc_blk_data {
126126
#define MMC_BLK_DISCARD BIT(2)
127127
#define MMC_BLK_SECDISCARD BIT(3)
128128
#define MMC_BLK_CQE_RECOVERY BIT(4)
129+
#define MMC_BLK_TRIM BIT(5)
129130

130131
/*
131132
* Only set in main mmc_blk_data associated
@@ -1092,12 +1093,13 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req)
10921093
blk_mq_end_request(req, ret ? BLK_STS_IOERR : BLK_STS_OK);
10931094
}
10941095

1095-
static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
1096+
static void mmc_blk_issue_erase_rq(struct mmc_queue *mq, struct request *req,
1097+
int type, unsigned int erase_arg)
10961098
{
10971099
struct mmc_blk_data *md = mq->blkdata;
10981100
struct mmc_card *card = md->queue.card;
10991101
unsigned int from, nr;
1100-
int err = 0, type = MMC_BLK_DISCARD;
1102+
int err = 0;
11011103
blk_status_t status = BLK_STS_OK;
11021104

11031105
if (!mmc_can_erase(card)) {
@@ -1113,13 +1115,13 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
11131115
if (card->quirks & MMC_QUIRK_INAND_CMD38) {
11141116
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
11151117
INAND_CMD38_ARG_EXT_CSD,
1116-
card->erase_arg == MMC_TRIM_ARG ?
1118+
erase_arg == MMC_TRIM_ARG ?
11171119
INAND_CMD38_ARG_TRIM :
11181120
INAND_CMD38_ARG_ERASE,
11191121
card->ext_csd.generic_cmd6_time);
11201122
}
11211123
if (!err)
1122-
err = mmc_erase(card, from, nr, card->erase_arg);
1124+
err = mmc_erase(card, from, nr, erase_arg);
11231125
} while (err == -EIO && !mmc_blk_reset(md, card->host, type));
11241126
if (err)
11251127
status = BLK_STS_IOERR;
@@ -1129,6 +1131,19 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
11291131
blk_mq_end_request(req, status);
11301132
}
11311133

1134+
static void mmc_blk_issue_trim_rq(struct mmc_queue *mq, struct request *req)
1135+
{
1136+
mmc_blk_issue_erase_rq(mq, req, MMC_BLK_TRIM, MMC_TRIM_ARG);
1137+
}
1138+
1139+
static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
1140+
{
1141+
struct mmc_blk_data *md = mq->blkdata;
1142+
struct mmc_card *card = md->queue.card;
1143+
1144+
mmc_blk_issue_erase_rq(mq, req, MMC_BLK_DISCARD, card->erase_arg);
1145+
}
1146+
11321147
static void mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
11331148
struct request *req)
11341149
{
@@ -2329,6 +2344,9 @@ enum mmc_issued mmc_blk_mq_issue_rq(struct mmc_queue *mq, struct request *req)
23292344
case REQ_OP_SECURE_ERASE:
23302345
mmc_blk_issue_secdiscard_rq(mq, req);
23312346
break;
2347+
case REQ_OP_WRITE_ZEROES:
2348+
mmc_blk_issue_trim_rq(mq, req);
2349+
break;
23322350
case REQ_OP_FLUSH:
23332351
mmc_blk_issue_flush(mq, req);
23342352
break;

drivers/mmc/core/queue.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ static void mmc_queue_setup_discard(struct request_queue *q,
191191
q->limits.discard_granularity = SECTOR_SIZE;
192192
if (mmc_can_secure_erase_trim(card))
193193
blk_queue_flag_set(QUEUE_FLAG_SECERASE, q);
194+
if (mmc_can_trim(card) && card->erased_byte == 0)
195+
blk_queue_max_write_zeroes_sectors(q, max_discard);
194196
}
195197

196198
static unsigned short mmc_get_max_segments(struct mmc_host *host)

0 commit comments

Comments
 (0)