v4 -> v5
- patche "Update ext_csd.cache_ctrl if it was written" accepted
- Add one more patch: "Add cache_enabled bus ops"
- Add Acked-by tag
- another rebase
v3 -> v4
- Attend Adrian's comments
- Add Acked-by tag
v2 -> v3:
- rebase onto recent cache changes
v1 -> v2:
- Attend Adrian's comments
Cache is a temporary storage space in an eMMC device. Volatile by
nature, the cache should in typical case reduce the access time compared
to an access to the main nonvolatile storage.
Avri Altman (2):
mmc: Add cache_enabled bus ops
mmc: block: Issue flush only if allowed
drivers/mmc/core/block.c | 9 +++++++++
drivers/mmc/core/core.h | 7 +++++++
drivers/mmc/core/mmc.c | 7 +++++++
drivers/mmc/core/mmc_ops.c | 4 +---
4 files changed, 24 insertions(+), 3 deletions(-)
--
2.25.1
Add a new bus ops callback ->cache_enabled() and implement it for the
mmc bus type.
From the mmc block layer point of view, it would then mean that if the
callback isn't implemented, the cache ctrl isn't supported (which
would be the case for SD then).
Going forward, newer SD cards support both cache and command queueing
nowadays, which means that we need to make the code in the mmc block
layer more agnostic. To do that, we should use the bus_ops callbacks,
e.g. adding the ->flush_cache() callback in the near future.
Signed-off-by: Avri Altman <[email protected]>
---
drivers/mmc/core/core.h | 9 +++++++++
drivers/mmc/core/mmc.c | 7 +++++++
drivers/mmc/core/mmc_ops.c | 4 +---
3 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 8032451abaea..db3c9c68875d 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -29,6 +29,7 @@ struct mmc_bus_ops {
int (*shutdown)(struct mmc_host *);
int (*hw_reset)(struct mmc_host *);
int (*sw_reset)(struct mmc_host *);
+ bool (*cache_enabled)(struct mmc_host *);
};
void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
@@ -163,4 +164,12 @@ static inline void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq,
host->ops->post_req(host, mrq, err);
}
+static inline bool mmc_cache_enabled(struct mmc_host *host)
+{
+ if (host->bus_ops->cache_enabled)
+ return host->bus_ops->cache_enabled(host);
+
+ return false;
+}
+
#endif
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index d35231feac68..8674c3e0c02c 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -2029,6 +2029,12 @@ static void mmc_detect(struct mmc_host *host)
}
}
+static bool _mmc_cache_enabled(struct mmc_host *host)
+{
+ return host->card->ext_csd.cache_size > 0 &&
+ host->card->ext_csd.cache_ctrl & 1;
+}
+
static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
{
int err = 0;
@@ -2208,6 +2214,7 @@ static const struct mmc_bus_ops mmc_ops = {
.alive = mmc_alive,
.shutdown = mmc_shutdown,
.hw_reset = _mmc_hw_reset,
+ .cache_enabled = _mmc_cache_enabled,
};
/*
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index cdf02d88fe92..5756781fef37 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -968,9 +968,7 @@ int mmc_flush_cache(struct mmc_card *card)
{
int err = 0;
- if (mmc_card_mmc(card) &&
- (card->ext_csd.cache_size > 0) &&
- (card->ext_csd.cache_ctrl & 1)) {
+ if (mmc_cache_enabled(card->host)) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_FLUSH_CACHE, 1,
MMC_CACHE_FLUSH_TIMEOUT_MS);
--
2.25.1
The cache may be flushed to the nonvolatile storage by writing to
FLUSH_CACHE byte (EXT_CSD byte [32]). When in command queueing mode, the
cache may be flushed by issuing a CMDQ_TASK_ DEV_MGMT (CMD48) with a
FLUSH_CACHE op-code. Either way, verify that The cache function is
turned ON before doing so.
fixes: 1e8e55b67030 (mmc: block: Add CQE support)
Reported-by: Brendan Peter <[email protected]>
Tested-by: Brendan Peter <[email protected]>
Signed-off-by: Avri Altman <[email protected]>
Acked-by: Adrian Hunter <[email protected]>
---
drivers/mmc/core/block.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 6cd5d03bcc64..e3062bbf110e 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -2198,6 +2198,11 @@ static int mmc_blk_wait_for_idle(struct mmc_queue *mq, struct mmc_host *host)
return mmc_blk_rw_wait(mq, NULL);
}
+static bool mmc_blk_cache_disabled(struct mmc_host *host)
+{
+ return !mmc_cache_enabled(host);
+}
+
enum mmc_issued mmc_blk_mq_issue_rq(struct mmc_queue *mq, struct request *req)
{
struct mmc_blk_data *md = mq->blkdata;
@@ -2237,6 +2242,10 @@ enum mmc_issued mmc_blk_mq_issue_rq(struct mmc_queue *mq, struct request *req)
case MMC_ISSUE_ASYNC:
switch (req_op(req)) {
case REQ_OP_FLUSH:
+ if (mmc_blk_cache_disabled(host)) {
+ blk_mq_end_request(req, BLK_STS_OK);
+ return MMC_REQ_FINISHED;
+ }
ret = mmc_blk_cqe_issue_flush(mq, req);
break;
case REQ_OP_READ:
--
2.25.1
On Sun, 25 Apr 2021 at 08:02, Avri Altman <[email protected]> wrote:
>
> v4 -> v5
> - patche "Update ext_csd.cache_ctrl if it was written" accepted
> - Add one more patch: "Add cache_enabled bus ops"
> - Add Acked-by tag
> - another rebase
>
> v3 -> v4
> - Attend Adrian's comments
> - Add Acked-by tag
>
> v2 -> v3:
> - rebase onto recent cache changes
>
> v1 -> v2:
> - Attend Adrian's comments
>
> Cache is a temporary storage space in an eMMC device. Volatile by
> nature, the cache should in typical case reduce the access time compared
> to an access to the main nonvolatile storage.
>
> Avri Altman (2):
> mmc: Add cache_enabled bus ops
> mmc: block: Issue flush only if allowed
>
> drivers/mmc/core/block.c | 9 +++++++++
> drivers/mmc/core/core.h | 7 +++++++
> drivers/mmc/core/mmc.c | 7 +++++++
> drivers/mmc/core/mmc_ops.c | 4 +---
> 4 files changed, 24 insertions(+), 3 deletions(-)
>
Normally, I would appreciate this split of the patches, but since
these are material for stable kernels I decided to squash the patches.
I also took the opportunity of updating the commit message a bit and
did a minor cleanup in the code. Please have a look at my next branch
and yell at me if there is something you don't like.
So, applied for next and by adding a stable tag, thanks!
Kind regards
Uffe
> Normally, I would appreciate this split of the patches, but since
> these are material for stable kernels I decided to squash the patches.
>
> I also took the opportunity of updating the commit message a bit and
> did a minor cleanup in the code. Please have a look at my next branch
> and yell at me if there is something you don't like.
Looks fine. Thanks a lot,
Avri
>
> So, applied for next and by adding a stable tag, thanks!
>
> Kind regards
> Uffe