Re: [PATCH v2] mmc : implement REQ_OP_WRITE_ZEROES

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Nov 9, 2017 at 9:50 PM, Jungseung Lee <js07.lee@xxxxxxxxxxx> wrote:
> The contents of a write block where the trim function has been applied
> shall be '0' or '1' and so some of eMMC devices return zeroes on read to
> the trimmed blocks.
>
> Use the behavior to implement REQ_OP_WRITES_ZEROES. We can only know the
> behavior based on individual device modles, so this patch adds a flag to
> the mmc quirk list for devices works that way. It also sets the new flag
> for one such known device.
>
> Signed-off-by: Jungseung Lee <js07.lee@xxxxxxxxxxx>

Ulf, Could you make time to comment for this patch?

Best Regards,
Jungseung Lee

> ---
>  drivers/mmc/core/block.c  | 8 ++++++--
>  drivers/mmc/core/queue.c  | 4 ++++
>  drivers/mmc/core/quirks.h | 7 +++++++
>  include/linux/mmc/card.h  | 1 +
>  4 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
> index ea80ff4..41c4ec1 100644
> --- a/drivers/mmc/core/block.c
> +++ b/drivers/mmc/core/block.c
> @@ -1273,9 +1273,10 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
>         struct mmc_card *card = md->queue.card;
>         unsigned int from, nr, arg;
>         int err = 0, type = MMC_BLK_DISCARD;
> +       int force_trim = (req_op(req) == REQ_OP_WRITE_ZEROES);
>         blk_status_t status = BLK_STS_OK;
>
> -       if (!mmc_can_erase(card)) {
> +       if (!mmc_can_erase(card) || (!mmc_can_trim(card) && force_trim)) {
>                 status = BLK_STS_NOTSUPP;
>                 goto fail;
>         }
> @@ -1283,7 +1284,9 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
>         from = blk_rq_pos(req);
>         nr = blk_rq_sectors(req);
>
> -       if (mmc_can_discard(card))
> +       if (force_trim)
> +               arg = MMC_TRIM_ARG;
> +       else if (mmc_can_discard(card))
>                 arg = MMC_DISCARD_ARG;
>         else if (mmc_can_trim(card))
>                 arg = MMC_TRIM_ARG;
> @@ -2032,6 +2035,7 @@ void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
>                                 mmc_blk_issue_rw_rq(mq, NULL);
>                         mmc_blk_issue_drv_op(mq, req);
>                         break;
> +               case REQ_OP_WRITE_ZEROES:
>                 case REQ_OP_DISCARD:
>                         /*
>                          * Complete ongoing async transfer before issuing
> diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c
> index 4f33d27..c18d2a1 100644
> --- a/drivers/mmc/core/queue.c
> +++ b/drivers/mmc/core/queue.c
> @@ -144,6 +144,10 @@ static void mmc_queue_setup_discard(struct request_queue *q,
>         /* granularity must not be greater than max. discard */
>         if (card->pref_erase > max_discard)
>                 q->limits.discard_granularity = 0;
> +
> +       if (card->quirks & MMC_QUIRK_TRIM_ZEROES)
> +               blk_queue_max_write_zeroes_sectors(q, UINT_MAX);
> +
>         if (mmc_can_secure_erase_trim(card))
>                 queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, q);
>  }
> diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h
> index fb72593..58871ac 100644
> --- a/drivers/mmc/core/quirks.h
> +++ b/drivers/mmc/core/quirks.h
> @@ -90,6 +90,13 @@ static const struct mmc_fixup mmc_blk_fixups[] = {
>         MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc,
>                   MMC_QUIRK_TRIM_BROKEN),
>
> +       /*
> +        * Some MMC cards deterministically returns zeroes on reads to
> +        * trimmed logical blocks.
> +        */
> +       MMC_FIXUP("8GME4R", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
> +                 MMC_QUIRK_TRIM_ZEROES),
> +
>         END_FIXUP
>  };
>
> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> index 279b390..d328d1f 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -268,6 +268,7 @@ struct mmc_card {
>  #define MMC_QUIRK_BROKEN_IRQ_POLLING   (1<<11) /* Polling SDIO_CCCR_INTx could create a fake interrupt */
>  #define MMC_QUIRK_TRIM_BROKEN  (1<<12)         /* Skip trim */
>  #define MMC_QUIRK_BROKEN_HPI   (1<<13)         /* Disable broken HPI support */
> +#define MMC_QUIRK_TRIM_ZEROES  (1<<14)         /* Return 0's on read to trimmed logical blocks */
>
>         bool                    reenable_cmdq;  /* Re-enable Command Queue */
>
> --
> 2.10.1
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux