Skip to content

Commit 6c0cedd

Browse files
ahunter6storulf
authored andcommitted
mmc: core: Introduce host claiming by context
Currently the host can be claimed by a task. Change this so that the host can be claimed by a context that may or may not be a task. This provides for the host to be claimed by a block driver queue to support blk-mq, while maintaining compatibility with the existing use of mmc_claim_host(). Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent 9ca28c5 commit 6c0cedd

File tree

7 files changed

+60
-19
lines changed

7 files changed

+60
-19
lines changed

drivers/mmc/core/block.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,7 +1989,7 @@ void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
19891989

19901990
if (req && !mq->qcnt)
19911991
/* claim host only for the first request */
1992-
mmc_get_card(card);
1992+
mmc_get_card(card, NULL);
19931993

19941994
ret = mmc_blk_part_switch(card, md->part_type);
19951995
if (ret) {
@@ -2052,7 +2052,7 @@ void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
20522052

20532053
out:
20542054
if (!mq->qcnt)
2055-
mmc_put_card(card);
2055+
mmc_put_card(card, NULL);
20562056
}
20572057

20582058
static inline int mmc_blk_readonly(struct mmc_card *card)

drivers/mmc/core/core.c

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -832,18 +832,47 @@ unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz)
832832
}
833833
EXPORT_SYMBOL(mmc_align_data_size);
834834

835+
/*
836+
* Allow claiming an already claimed host if the context is the same or there is
837+
* no context but the task is the same.
838+
*/
839+
static inline bool mmc_ctx_matches(struct mmc_host *host, struct mmc_ctx *ctx,
840+
struct task_struct *task)
841+
{
842+
return host->claimer == ctx ||
843+
(!ctx && task && host->claimer->task == task);
844+
}
845+
846+
static inline void mmc_ctx_set_claimer(struct mmc_host *host,
847+
struct mmc_ctx *ctx,
848+
struct task_struct *task)
849+
{
850+
if (!host->claimer) {
851+
if (ctx)
852+
host->claimer = ctx;
853+
else
854+
host->claimer = &host->default_ctx;
855+
}
856+
if (task)
857+
host->claimer->task = task;
858+
}
859+
835860
/**
836861
* __mmc_claim_host - exclusively claim a host
837862
* @host: mmc host to claim
863+
* @ctx: context that claims the host or NULL in which case the default
864+
* context will be used
838865
* @abort: whether or not the operation should be aborted
839866
*
840867
* Claim a host for a set of operations. If @abort is non null and
841868
* dereference a non-zero value then this will return prematurely with
842869
* that non-zero value without acquiring the lock. Returns zero
843870
* with the lock held otherwise.
844871
*/
845-
int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
872+
int __mmc_claim_host(struct mmc_host *host, struct mmc_ctx *ctx,
873+
atomic_t *abort)
846874
{
875+
struct task_struct *task = ctx ? NULL : current;
847876
DECLARE_WAITQUEUE(wait, current);
848877
unsigned long flags;
849878
int stop;
@@ -856,7 +885,7 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
856885
while (1) {
857886
set_current_state(TASK_UNINTERRUPTIBLE);
858887
stop = abort ? atomic_read(abort) : 0;
859-
if (stop || !host->claimed || host->claimer == current)
888+
if (stop || !host->claimed || mmc_ctx_matches(host, ctx, task))
860889
break;
861890
spin_unlock_irqrestore(&host->lock, flags);
862891
schedule();
@@ -865,7 +894,7 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
865894
set_current_state(TASK_RUNNING);
866895
if (!stop) {
867896
host->claimed = 1;
868-
host->claimer = current;
897+
mmc_ctx_set_claimer(host, ctx, task);
869898
host->claim_cnt += 1;
870899
if (host->claim_cnt == 1)
871900
pm = true;
@@ -900,6 +929,7 @@ void mmc_release_host(struct mmc_host *host)
900929
spin_unlock_irqrestore(&host->lock, flags);
901930
} else {
902931
host->claimed = 0;
932+
host->claimer->task = NULL;
903933
host->claimer = NULL;
904934
spin_unlock_irqrestore(&host->lock, flags);
905935
wake_up(&host->wq);
@@ -913,20 +943,24 @@ EXPORT_SYMBOL(mmc_release_host);
913943
* This is a helper function, which fetches a runtime pm reference for the
914944
* card device and also claims the host.
915945
*/
916-
void mmc_get_card(struct mmc_card *card)
946+
void mmc_get_card(struct mmc_card *card, struct mmc_ctx *ctx)
917947
{
918948
pm_runtime_get_sync(&card->dev);
919-
mmc_claim_host(card->host);
949+
__mmc_claim_host(card->host, ctx, NULL);
920950
}
921951
EXPORT_SYMBOL(mmc_get_card);
922952

923953
/*
924954
* This is a helper function, which releases the host and drops the runtime
925955
* pm reference for the card device.
926956
*/
927-
void mmc_put_card(struct mmc_card *card)
957+
void mmc_put_card(struct mmc_card *card, struct mmc_ctx *ctx)
928958
{
929-
mmc_release_host(card->host);
959+
struct mmc_host *host = card->host;
960+
961+
WARN_ON(ctx && host->claimer != ctx);
962+
963+
mmc_release_host(host);
930964
pm_runtime_mark_last_busy(&card->dev);
931965
pm_runtime_put_autosuspend(&card->dev);
932966
}

drivers/mmc/core/core.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,11 @@ int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen);
128128
int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount,
129129
bool is_rel_write);
130130

131-
int __mmc_claim_host(struct mmc_host *host, atomic_t *abort);
131+
int __mmc_claim_host(struct mmc_host *host, struct mmc_ctx *ctx,
132+
atomic_t *abort);
132133
void mmc_release_host(struct mmc_host *host);
133-
void mmc_get_card(struct mmc_card *card);
134-
void mmc_put_card(struct mmc_card *card);
134+
void mmc_get_card(struct mmc_card *card, struct mmc_ctx *ctx);
135+
void mmc_put_card(struct mmc_card *card, struct mmc_ctx *ctx);
135136

136137
/**
137138
* mmc_claim_host - exclusively claim a host
@@ -141,7 +142,7 @@ void mmc_put_card(struct mmc_card *card);
141142
*/
142143
static inline void mmc_claim_host(struct mmc_host *host)
143144
{
144-
__mmc_claim_host(host, NULL);
145+
__mmc_claim_host(host, NULL, NULL);
145146
}
146147

147148
#endif

drivers/mmc/core/mmc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1911,14 +1911,14 @@ static void mmc_detect(struct mmc_host *host)
19111911
{
19121912
int err;
19131913

1914-
mmc_get_card(host->card);
1914+
mmc_get_card(host->card, NULL);
19151915

19161916
/*
19171917
* Just check if our card has been removed.
19181918
*/
19191919
err = _mmc_detect_card_removed(host);
19201920

1921-
mmc_put_card(host->card);
1921+
mmc_put_card(host->card, NULL);
19221922

19231923
if (err) {
19241924
mmc_remove(host);

drivers/mmc/core/sd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,14 +1056,14 @@ static void mmc_sd_detect(struct mmc_host *host)
10561056
{
10571057
int err;
10581058

1059-
mmc_get_card(host->card);
1059+
mmc_get_card(host->card, NULL);
10601060

10611061
/*
10621062
* Just check if our card has been removed.
10631063
*/
10641064
err = _mmc_detect_card_removed(host);
10651065

1066-
mmc_put_card(host->card);
1066+
mmc_put_card(host->card, NULL);
10671067

10681068
if (err) {
10691069
mmc_sd_remove(host);

drivers/mmc/core/sdio_irq.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ static int sdio_irq_thread(void *_host)
155155
* holding of the host lock does not cover too much work
156156
* that doesn't require that lock to be held.
157157
*/
158-
ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort);
158+
ret = __mmc_claim_host(host, NULL,
159+
&host->sdio_irq_thread_abort);
159160
if (ret)
160161
break;
161162
ret = process_sdio_pending_irqs(host);

include/linux/mmc/host.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ struct mmc_supply {
255255
struct regulator *vqmmc; /* Optional Vccq supply */
256256
};
257257

258+
struct mmc_ctx {
259+
struct task_struct *task;
260+
};
261+
258262
struct mmc_host {
259263
struct device *parent;
260264
struct device class_dev;
@@ -388,8 +392,9 @@ struct mmc_host {
388392
struct mmc_card *card; /* device attached to this host */
389393

390394
wait_queue_head_t wq;
391-
struct task_struct *claimer; /* task that has host claimed */
395+
struct mmc_ctx *claimer; /* context that has host claimed */
392396
int claim_cnt; /* "claim" nesting count */
397+
struct mmc_ctx default_ctx; /* default context */
393398

394399
struct delayed_work detect;
395400
int detect_change; /* card detect flag */

0 commit comments

Comments
 (0)