From: Sujit Reddy Thumma <sthumma@codeaurora.org>
To: Per Forlin <per.lkml@gmail.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>,
linux-mmc@vger.kernel.org, linux-arm-msm@vger.kernel.org,
cjb@laptop.org
Subject: Re: [PATCH] mmc: core: Kill block requests if card is removed
Date: Mon, 14 Nov 2011 14:16:46 +0530 [thread overview]
Message-ID: <4EC0D576.6070000@codeaurora.org> (raw)
In-Reply-To: <CAFEEs1kXy4GB-kWZ++v7tBPeDj=HJqj+Tcv+tnmvV_O86xbuBA@mail.gmail.com>
On 11/14/2011 1:54 PM, Per Forlin wrote:
> On Mon, Nov 14, 2011 at 8:52 AM, Per Forlin<per.lkml@gmail.com> wrote:
>> On Mon, Nov 14, 2011 at 5:19 AM, Sujit Reddy Thumma
>> <sthumma@codeaurora.org> wrote:
>>> On 11/10/2011 7:50 PM, Per Forlin wrote:
>>>>
>>>> On Thu, Nov 10, 2011 at 10:35 AM, Adrian Hunter<adrian.hunter@intel.com>
>>>> wrote:
>>>>>
>>>>> On 10/11/11 06:02, Sujit Reddy Thumma wrote:
>>>>>>
>>>>>> Hi,
>>>>>>>
>>>>>>> Hi Adrian,
>>>>>>>
>>>>>>> On Wed, Nov 9, 2011 at 10:34 AM, Adrian Hunter<adrian.hunter@intel.com>
>>>>>>> wrote:
>>>>>>>>
>>>>>>>> On 09/11/11 06:31, Sujit Reddy Thumma wrote:
>>>>>>>>>
>>>>>>>>> Kill block requests when the host knows that the card is
>>>>>>>>> removed from the slot and is sure that subsequent requests
>>>>>>>>> are bound to fail. Do this silently so that the block
>>>>>>>>> layer doesn't output unnecessary error messages.
>>>>>>>>>
>>>>>>>>> This patch implements suggestion from Adrian Hunter,
>>>>>>>>> http://thread.gmane.org/gmane.linux.kernel.mmc/2714/focus=3474
>>>>>>>>>
>>>>>>>>> Signed-off-by: Sujit Reddy Thumma<sthumma@codeaurora.org>
>>>>>>>>> ---
>>>>>>>>
>>>>>>>>
>>>>>>>> It is safer to have zero initialisations so I suggest inverting
>>>>>>>> the meaning of the state bit i.e.
>>>>>>
>>>>>> Makes sense. Will take care in V2.
>>>>>>
>>>>>>>>
>>>>>>>> #define MMC_STATE_CARD_GONE (1<<7) /* card removed from
>>>>>>>> the
>>>>>>>> slot */
>>>>>>>>
>>>>>>>>
>>>>>>>> Also it would be nice is a request did not start if the card is
>>>>>>>> gone. For the non-async case, that is easy:
>>>>>>>>
>>>>>>> As far as I understand Sujit's patch it will stop new requests from
>>>>>>> being issued, blk_fetch_request(q) returns NULL.
>>>>>>
>>>>>> Yes, Per you are right. The ongoing requests will fail at the controller
>>>>>> driver layer and only the new requests coming to MMC queue layer will be
>>>>>> blocked.
>>>>>>
>>>>>> Adrian's suggestion is to stop all the requests reaching host controller
>>>>>> layer by mmc core. This seems to be a good approach but the problem here
>>>>>> is
>>>>>> the host driver should inform mmc core that card is gone.
>>>>>>
>>>>>> Adrian, do you agree if we need to change all the host drivers to set
>>>>>> the
>>>>>> MMC_STATE_CARD_GONE flag as soon as the card detect irq handler detects
>>>>>> the
>>>>>> card as removed?
>>>>>
>>>>> Typically a card detect interrupt queues a rescan which in turn will have
>>>>> to wait to claim the host. In the meantime, in the async case, the block
>>>>> driver will not release the host until the queue is empty.
>>>>
>>>> Here is a patch that let async-mmc release host and reclaim it in case of
>>>> error.
>>>> When the host is released mmc_rescan will claim the host and run.
>>>> --------------------------------
>>>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>>>> index cf73877..8952e63 100644
>>>> --- a/drivers/mmc/card/block.c
>>>> +++ b/drivers/mmc/card/block.c
>>>> @@ -1209,6 +1209,28 @@ static int mmc_blk_cmd_err(struct mmc_blk_data
>>>> *md, struct mmc_card *card,
>>>> return ret;
>>>> }
>>>>
>>>> +/*
>>>> + * This function should be called to resend a request after failure.
>>>> + * Prepares and starts the request.
>>>> + */
>>>> +static inline struct mmc_async_req *mmc_blk_resend(struct mmc_card *card,
>>>> + struct mmc_queue *mq,
>>>> + struct mmc_queue_req
>>>> *mqrq,
>>>> + int disable_multi,
>>>> + struct mmc_async_req
>>>> *areq)
>>>> +{
>>>> + /*
>>>> + * Release host after failure in case the host is needed
>>>> + * by someone else. For instance, if the card is removed the
>>>> + * worker thread needs to claim the host in order to do
>>>> mmc_rescan.
>>>> + */
>>>> + mmc_release_host(card->host);
>>>> + mmc_claim_host(card->host);
>>>> +
>>>> + mmc_blk_rw_rq_prep(mqrq, card, disable_multi, mq);
>>>> + return mmc_start_req(card->host, areq, NULL);
>>>> +}
>>>> +
>>>> static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
>>>> {
>>>> struct mmc_blk_data *md = mq->data;
>>>> @@ -1308,14 +1330,14 @@ static int mmc_blk_issue_rw_rq(struct
>>>> mmc_queue *mq, struct request *rqc)
>>>> break;
>>>> }
>>>>
>>>> - if (ret) {
>>>> + if (ret)
>>>> /*
>>>> * In case of a incomplete request
>>>> * prepare it again and resend.
>>>> */
>>>> - mmc_blk_rw_rq_prep(mq_rq, card, disable_multi,
>>>> mq);
>>>> - mmc_start_req(card->host,&mq_rq->mmc_active,
>>>> NULL);
>>>> - }
>>>> + mmc_blk_prep_start(card, mq, mq_rq, disable_multi,
>>>> +&mq_rq->mmc_active);
>>>> +
>>>
>>> :%s/mmc_blk_prep_start/mmc_blk_resend
>>>
>> I'll update.
>>
>>>> } while (ret);
>>>>
>>>> return 1;
>>>> @@ -1327,10 +1349,9 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue
>>>> *mq, struct request *rqc)
>>>> spin_unlock_irq(&md->lock);
>>>>
>>>> start_new_req:
>>>> - if (rqc) {
>>>> - mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
>>>> - mmc_start_req(card->host,&mq->mqrq_cur->mmc_active, NULL);
>>>> - }
>>>> + if (rqc)
>>>> + mmc_blk_prep_start(card, mq, mq->mqrq_cur, 0,
>>>> +&mq->mqrq_cur->mmc_active);
>>>>
>>>> return 0;
>>>> }
>>>
>>> Thanks Per. This looks good. Can we split this into a different patch?
>>>
>> Yes I agree. My intention was to treat this as a separate patch.
>> I'll post it.
>>
>>>> -------------------------------------
>>>>
>>>>
>>>>> The block
>>>>> driver will see errors and will use a send status command which will fail
>>>>> so the request will be aborted, but the next request will be started
>>>>> anyway.
>>>>>
>>>>> There are two problems:
>>>>>
>>>>> 1. When do we reliably know that the card has really gone?
>>>>>
>>>>> At present, the detect method for SD and MMC is just the send status
>>>>> command, which is what the block driver is doing i.e. if the block
>>>>> driver sees send status fail, after an errored request, and the
>>>>> card is removable, then it is very likely the card has gone.
>>>>>
>>>>> At present, it is not considered that the host controller driver
>>>>> knows whether the card is really gone - just that it might be.
>>>>>
>>>>> Setting a MMC_STATE_CARD_GONE flag early may be a little complicated.
>>>>> e.g. mmc_detect_change() flags that the card may be gone. After an
>>>>> error, if the "card may be gone" flag is set a new bus method could
>>>>> be called that just does send status. If that fails, then the
>>>>> MMC_STATE_CARD_GONE flag is set. Any calls to the detect method
>>>>> must first check the MMC_STATE_CARD_GONE flag so that, once gone,
>>>>> a card can not come back.
>>>>>
>>>>> Maybe you can think of something simpler.
>>>
>>> Can we do something like this:
>>>
>>> --- a/drivers/mmc/card/block.c
>>> +++ b/drivers/mmc/card/block.c
>>> @@ -648,8 +648,15 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card,
>>> struct request *req,
>>> }
>>>
>>> /* We couldn't get a response from the card. Give up. */
>>> - if (err)
>>> + if (err) {
>>> + /*
>>> + * If the card didn't respond to status command,
>>> + * it is likely that card is gone. Flag it as removed,
>>> + * mmc_detect_change() cleans the rest.
>>> + */
>>> + mmc_card_set_card_gone(card);
>>> return ERR_ABORT;
>>> + }
>>>
>>> /* Flag ECC errors */
>>> if ((status& R1_CARD_ECC_FAILED) ||
>>>
>>> and some additions to Per's patch, changes denoted in (++):
>>>
>>> +/*
>>> + * This function should be called to resend a request after failure.
>>> + * Prepares and starts the request.
>>> + */
>>> +static inline struct mmc_async_req *mmc_blk_resend(struct mmc_card *card,
>>> + struct mmc_queue *mq,
>>> + struct mmc_queue_req
>>> *mqrq,
>>> + int disable_multi,
>>> + struct mmc_async_req
>>> *areq)
>>> +{
>>> + /*
>>> + * Release host after failure in case the host is needed
>>> + * by someone else. For instance, if the card is removed the
>>> + * worker thread needs to claim the host in order to do mmc_rescan.
>>> + */
>>> + mmc_release_host(card->host);
>>> + mmc_claim_host(card->host);
>>> ++ if (mmc_card_gone(card)) {
>>> ++ /*
>>> ++ * End the pending async request without starting it when card
>>> ++ * is removed.
>>> ++ */
>>> ++ req->cmd_flags |= REQ_QUIET;
>>> ++ __blk_end_request(req, -EIO, blk_rq_cur_bytes(req));
>> I'll add this to the patch and send it out.
> I'll wait adding this since mmc_card_gone() is not available yet.
> Maybe we should send these two patches (aync error release and kill
> block request) in the same patch-set?
I think we can split this up without having this change in your patch. I
can add this as part of kill block request change itself which makes
your patch independent.
>
> Thanks,
> Per
--
Thanks,
Sujit
next prev parent reply other threads:[~2011-11-14 8:46 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-09 4:31 [PATCH] mmc: core: Kill block requests if card is removed Sujit Reddy Thumma
2011-11-09 9:34 ` Adrian Hunter
2011-11-09 20:53 ` Per Forlin
2011-11-09 22:05 ` Per Forlin
2011-11-10 4:13 ` Sujit Reddy Thumma
2011-11-10 4:02 ` Sujit Reddy Thumma
2011-11-10 9:35 ` Adrian Hunter
2011-11-10 14:20 ` Per Forlin
2011-11-14 4:19 ` Sujit Reddy Thumma
2011-11-14 7:52 ` Per Forlin
2011-11-14 8:24 ` Per Forlin
2011-11-14 8:46 ` Sujit Reddy Thumma [this message]
2011-11-09 21:47 ` Per Forlin
2011-11-10 5:31 ` Sujit Reddy Thumma
2011-11-22 20:18 ` David Taylor
2011-11-24 9:30 ` Per Forlin
2011-11-24 11:31 ` Sujit Reddy Thumma
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4EC0D576.6070000@codeaurora.org \
--to=sthumma@codeaurora.org \
--cc=adrian.hunter@intel.com \
--cc=cjb@laptop.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-mmc@vger.kernel.org \
--cc=per.lkml@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox