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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.