]> git.ipfire.org Git - thirdparty/openwrt.git/blob
881921cd07dc924eb3feb46e2737cb08f1e68546
[thirdparty/openwrt.git] /
1 From 514dc2cbb79cc42d4057278d4a207aca13f6afeb Mon Sep 17 00:00:00 2001
2 From: Jonathan Bell <jonathan@raspberrypi.com>
3 Date: Thu, 20 Jun 2024 14:31:20 +0100
4 Subject: [PATCH] mmc: restrict posted write counts for SD cards in CQ mode
5
6 Command Queueing requires Write Cache and Power off Notification support
7 from the card - but using the write cache forms a contract with the host
8 whereby the card expects to be told about impending power-down.
9
10 The implication is that (for performance) the card can do unsafe things
11 with pending write data - including reordering what gets committed to
12 nonvolatile storage at what time.
13
14 Exposed SD slots and platforms powered by hotpluggable means (i.e.
15 Raspberry Pis) can't guarantee that surprise removal won't happen.
16
17 To limit the scope for cards to invent new ways to trash filesystems,
18 limit pending writes to 1 (equivalent to the non-CQ behaviour).
19
20 Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
21
22 fixup: mmc: restrict posted write counts for SD cards in CQ mode
23
24 Leaving card->max_posted_writes unintialised was a bad thing to do.
25
26 Also, cqe_enable is 1 if hsq is enabled as hsq substitutes the cqhci
27 implementation with its own.
28
29 Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
30 ---
31 drivers/mmc/core/block.c | 11 +++++++++--
32 drivers/mmc/core/mmc.c | 2 ++
33 drivers/mmc/core/queue.c | 9 +++++++++
34 drivers/mmc/core/queue.h | 1 +
35 drivers/mmc/core/sd.c | 10 ++++++++++
36 include/linux/mmc/card.h | 2 ++
37 6 files changed, 33 insertions(+), 2 deletions(-)
38
39 --- a/drivers/mmc/core/block.c
40 +++ b/drivers/mmc/core/block.c
41 @@ -1617,6 +1617,8 @@ static void mmc_blk_cqe_complete_rq(stru
42
43 spin_lock_irqsave(&mq->lock, flags);
44
45 + if (req_op(req) == REQ_OP_WRITE)
46 + mq->pending_writes--;
47 mq->in_flight[issue_type] -= 1;
48
49 put_card = (mmc_tot_in_flight(mq) == 0);
50 @@ -2133,6 +2135,8 @@ static void mmc_blk_mq_complete_rq(struc
51 struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
52 unsigned int nr_bytes = mqrq->brq.data.bytes_xfered;
53
54 + if (req_op(req) == REQ_OP_WRITE)
55 + mq->pending_writes--;
56 if (nr_bytes) {
57 if (blk_update_request(req, BLK_STS_OK, nr_bytes))
58 blk_mq_requeue_request(req, true);
59 @@ -2227,13 +2231,16 @@ static void mmc_blk_mq_poll_completion(s
60 mmc_blk_urgent_bkops(mq, mqrq);
61 }
62
63 -static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, enum mmc_issue_type issue_type)
64 +static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, enum mmc_issue_type issue_type,
65 + struct request *req)
66 {
67 unsigned long flags;
68 bool put_card;
69
70 spin_lock_irqsave(&mq->lock, flags);
71
72 + if (req_op(req) == REQ_OP_WRITE)
73 + mq->pending_writes--;
74 mq->in_flight[issue_type] -= 1;
75
76 put_card = (mmc_tot_in_flight(mq) == 0);
77 @@ -2267,7 +2274,7 @@ static void mmc_blk_mq_post_req(struct m
78 blk_mq_complete_request(req);
79 }
80
81 - mmc_blk_mq_dec_in_flight(mq, issue_type);
82 + mmc_blk_mq_dec_in_flight(mq, issue_type, req);
83 }
84
85 void mmc_blk_mq_recovery(struct mmc_queue *mq)
86 --- a/drivers/mmc/core/mmc.c
87 +++ b/drivers/mmc/core/mmc.c
88 @@ -1657,6 +1657,7 @@ static int mmc_init_card(struct mmc_host
89 card->ocr = ocr;
90 card->type = MMC_TYPE_MMC;
91 card->rca = 1;
92 + card->max_posted_writes = 1;
93 memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
94 }
95
96 @@ -1922,6 +1923,7 @@ static int mmc_init_card(struct mmc_host
97 pr_info("%s: Host Software Queue enabled\n",
98 mmc_hostname(host));
99 }
100 + card->max_posted_writes = card->ext_csd.cmdq_depth;
101 }
102 }
103
104 --- a/drivers/mmc/core/queue.c
105 +++ b/drivers/mmc/core/queue.c
106 @@ -266,6 +266,11 @@ static blk_status_t mmc_mq_queue_rq(stru
107 spin_unlock_irq(&mq->lock);
108 return BLK_STS_RESOURCE;
109 }
110 + if (!host->hsq_enabled && host->cqe_enabled && req_op(req) == REQ_OP_WRITE &&
111 + mq->pending_writes >= card->max_posted_writes) {
112 + spin_unlock_irq(&mq->lock);
113 + return BLK_STS_RESOURCE;
114 + }
115 break;
116 default:
117 /*
118 @@ -282,6 +287,8 @@ static blk_status_t mmc_mq_queue_rq(stru
119 /* Parallel dispatch of requests is not supported at the moment */
120 mq->busy = true;
121
122 + if (req_op(req) == REQ_OP_WRITE)
123 + mq->pending_writes++;
124 mq->in_flight[issue_type] += 1;
125 get_card = (mmc_tot_in_flight(mq) == 1);
126 cqe_retune_ok = (mmc_cqe_qcnt(mq) == 1);
127 @@ -321,6 +328,8 @@ static blk_status_t mmc_mq_queue_rq(stru
128 bool put_card = false;
129
130 spin_lock_irq(&mq->lock);
131 + if (req_op(req) == REQ_OP_WRITE)
132 + mq->pending_writes--;
133 mq->in_flight[issue_type] -= 1;
134 if (mmc_tot_in_flight(mq) == 0)
135 put_card = true;
136 --- a/drivers/mmc/core/queue.h
137 +++ b/drivers/mmc/core/queue.h
138 @@ -79,6 +79,7 @@ struct mmc_queue {
139 struct request_queue *queue;
140 spinlock_t lock;
141 int in_flight[MMC_ISSUE_MAX];
142 + int pending_writes;
143 unsigned int cqe_busy;
144 #define MMC_CQE_DCMD_BUSY BIT(0)
145 bool busy;
146 --- a/drivers/mmc/core/sd.c
147 +++ b/drivers/mmc/core/sd.c
148 @@ -1099,6 +1099,15 @@ static int sd_parse_ext_reg_perf(struct
149 pr_debug("%s: Command Queue supported depth %u\n",
150 mmc_hostname(card->host),
151 card->ext_csd.cmdq_depth);
152 + /*
153 + * If CQ is enabled, there is a contract between host and card such that
154 + * VDD will be maintained and removed only if a power off notification
155 + * is provided. An SD card in an accessible slot means surprise removal
156 + * is a possibility. As a middle ground, keep the default maximum of 1
157 + * posted write unless the card is "hardwired".
158 + */
159 + if (!mmc_card_is_removable(card->host))
160 + card->max_posted_writes = card->ext_csd.cmdq_depth;
161 }
162
163 card->ext_perf.fno = fno;
164 @@ -1362,6 +1371,7 @@ retry:
165
166 card->ocr = ocr;
167 card->type = MMC_TYPE_SD;
168 + card->max_posted_writes = 1;
169 memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
170 }
171
172 --- a/include/linux/mmc/card.h
173 +++ b/include/linux/mmc/card.h
174 @@ -343,6 +343,8 @@ struct mmc_card {
175 unsigned int nr_parts;
176
177 struct workqueue_struct *complete_wq; /* Private workqueue */
178 +
179 + unsigned int max_posted_writes; /* command queue posted write limit */
180 };
181
182 static inline bool mmc_large_sector(struct mmc_card *card)