Re: [PATCH v3] mmc: support BKOPS feature for eMMC
Hi Konstantin. Thanks for your comment.. I will consider your opinion and send path-v4...then also let me know more comments :) Best Regards, Jaehoon Chung 2011/12/2 Konstantin Dorfman : > Hello Jaehoon, > After applying your patch and debugging it for some time, > I want to share my results and suggests some changes to the patch. > See comments below: > >> +void mmc_start_bkops(struct mmc_card *card) >> +{ >> + int err; >> + unsigned long flags; >> + >> + BUG_ON(!card); >> + if ((!card->ext_csd.bkops_en) || >> + !(card->host->caps2 & MMC_CAP2_BKOPS)) >> + return; >> + >> + /* >> + * If card is already doing bkops or need for >> + * bkops flag is not set, then do nothing just >> + * return >> + */ >> + if (mmc_card_doing_bkops(card) >> + || !mmc_card_need_bkops(card)) >> + return; >> + >> + mmc_claim_host(card->host); >> + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, >> + EXT_CSD_BKOPS_START, 1, 0); >> + if (err) { >> + pr_warning("error %d starting bkops\n", err); >> + mmc_card_clr_need_bkops(card); >> + goto out; >> + } >> + spin_lock_irqsave(&card->host->lock, flags); >> + mmc_card_clr_need_bkops(card); >> + mmc_card_set_doing_bkops(card); > > mmc_switch() will use CMD6 with MMC_RSP_R1B flag (see mmc_switch() > implementation), this flag > causes mmc controler to wait until busy line (DAT0) released: > > from eMMC v4.5 protocol > 6.12 Responses > ... > R1b is identical to R1 with an optional busy signal transmitted on the > data line DAT0. > The Device may become busy after receiving these commands based on its > state prior to the command reception. > ... > 7.4.56 BKOPS_START [164] > Writing any value to this field shall manually start background > operations. Device shall stay busy till no more > background operations are needed. > cut > > This means, that mmc_switch() returns only after BKOPS finished by card > and there is no point > in setting mmc_card_set_doing_bkops(card). Also, HPI command send to the > card in order to interrupt BKOPS in mmc_queue_thread() > will never actually interrupt BKOPS. To resolve this I suggest following: > > 1) Define two variants of mmc_switch(...,wait_flag) for BKOPS, where > wait_flag is true sends CMD6 with MMC_RSP_R1b flag as it happens now. > wait_flag is false sends CMD6 with MMC_RSP_R1 flag (the only > difference is MMC_RSP_BUSY bit), > so the flow continues immediately after CMD response arrives and will > not wait for busy line release. > > 2) The only situation when we want to use synchronous mmc_switch(..., > true) is URGENT bit arrives from card, in mmc_blk_issue_rw_rq(). > There is no point in waiting for idle time check in mmc_queue_thread(), > host should start synchronous BKOPS immediately. > > 3) When in idle (no requests to issue) we can read BKOPS_STATUS[246] from > card and depending on state decide: > 0: nothing to do go idle > 1: start BKOPS with no wait for busy line ( mmc_switch(..., false)) > and mmc_set_doing_bkops() > 3&2: start synchronous BKOPS > > Let me describe this by pseudo-code below: > > queue.c: mmc_queue_thread(): > ... > req = blk_fetch_request(q) > if(req == NULL) { > state = read_bkops_state(); // read BKOPS_STATUS[246] from card > switch(state) { > case 0: > go_idle() > break; > case 1: > start_asynch_bkops() // send CMD6 with no wait for busy > mmc_set_doing_bkops() // update flag > break; > case 2: > case 3: > start_synch_bkops() // start CMD6 with wait for busy > break; > default: > go_idle() > } > } else { > if( mmc_doing_bkops() ) { > mmc_send_hpi() > mmc_clear_doing_bkops() > } > issue(req) > } > > mmc\card\block.c: mmc_blk_issue_rw_rq() > ... > if ( (mmc_is_exception_event(card,EXT_CSD_URGENT_BKOPS)) { > start_synch_bkops() // start CMD6 with wait for busy > } > ... > ---end of pseudo code- > > Does this make sense? > Thanks, Kostya > > > > -- > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] mmc: support BKOPS feature for eMMC
Hello Jaehoon, After applying your patch and debugging it for some time, I want to share my results and suggests some changes to the patch. See comments below: > +void mmc_start_bkops(struct mmc_card *card) > +{ > + int err; > + unsigned long flags; > + > + BUG_ON(!card); > + if ((!card->ext_csd.bkops_en) || > + !(card->host->caps2 & MMC_CAP2_BKOPS)) > + return; > + > + /* > + * If card is already doing bkops or need for > + * bkops flag is not set, then do nothing just > + * return > + */ > + if (mmc_card_doing_bkops(card) > + || !mmc_card_need_bkops(card)) > + return; > + > + mmc_claim_host(card->host); > + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, > + EXT_CSD_BKOPS_START, 1, 0); > + if (err) { > + pr_warning("error %d starting bkops\n", err); > + mmc_card_clr_need_bkops(card); > + goto out; > + } > + spin_lock_irqsave(&card->host->lock, flags); > + mmc_card_clr_need_bkops(card); > + mmc_card_set_doing_bkops(card); mmc_switch() will use CMD6 with MMC_RSP_R1B flag (see mmc_switch() implementation), this flag causes mmc controler to wait until busy line (DAT0) released: from eMMC v4.5 protocol 6.12 Responses ... R1b is identical to R1 with an optional busy signal transmitted on the data line DAT0. The Device may become busy after receiving these commands based on its state prior to the command reception. ... 7.4.56 BKOPS_START [164] Writing any value to this field shall manually start background operations. Device shall stay busy till no more background operations are needed. cut This means, that mmc_switch() returns only after BKOPS finished by card and there is no point in setting mmc_card_set_doing_bkops(card). Also, HPI command send to the card in order to interrupt BKOPS in mmc_queue_thread() will never actually interrupt BKOPS. To resolve this I suggest following: 1) Define two variants of mmc_switch(...,wait_flag) for BKOPS, where wait_flag is true sends CMD6 with MMC_RSP_R1b flag as it happens now. wait_flag is false sends CMD6 with MMC_RSP_R1 flag (the only difference is MMC_RSP_BUSY bit), so the flow continues immediately after CMD response arrives and will not wait for busy line release. 2) The only situation when we want to use synchronous mmc_switch(..., true) is URGENT bit arrives from card, in mmc_blk_issue_rw_rq(). There is no point in waiting for idle time check in mmc_queue_thread(), host should start synchronous BKOPS immediately. 3) When in idle (no requests to issue) we can read BKOPS_STATUS[246] from card and depending on state decide: 0: nothing to do go idle 1: start BKOPS with no wait for busy line ( mmc_switch(..., false)) and mmc_set_doing_bkops() 3&2: start synchronous BKOPS Let me describe this by pseudo-code below: queue.c: mmc_queue_thread(): ... req = blk_fetch_request(q) if(req == NULL) { state = read_bkops_state(); // read BKOPS_STATUS[246] from card switch(state) { case 0: go_idle() break; case 1: start_asynch_bkops() // send CMD6 with no wait for busy mmc_set_doing_bkops() // update flag break; case 2: case 3: start_synch_bkops() // start CMD6 with wait for busy break; default: go_idle() } } else { if( mmc_doing_bkops() ) { mmc_send_hpi() mmc_clear_doing_bkops() } issue(req) } mmc\card\block.c: mmc_blk_issue_rw_rq() ... if ( (mmc_is_exception_event(card,EXT_CSD_URGENT_BKOPS)) { start_synch_bkops() // start CMD6 with wait for busy } ... ---end of pseudo code- Does this make sense? Thanks, Kostya -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] mmc: support BKOPS feature for eMMC
Hi Adrian. On 11/29/2011 09:20 PM, Adrian Hunter wrote: > On 17/11/11 02:50, Jaehoon Chung wrote: >> Enable eMMC background operations (BKOPS) feature. >> >> If URGENT_BKOPS is set after a response, note that BKOPS >> are required. After all I/O requests are finished, run >> BKOPS if required. Should read/write operations be requested >> during BKOPS, first issue HPI to interrupt the ongoing BKOPS >> and then service the request. >> >> If you want to enable this feature, set MMC_CAP2_BKOPS. >> >> Future considerations >> * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner. >> * Interrupt ongoing BKOPS before powering off the card. >> >> Signed-off-by: Jaehoon Chung >> Signed-off-by: Kyungmin Park >> CC: Hanumath Prasad >> --- >> Changelog V3: >> - move the bkops setting's location in mmc_blk_issue_rw_rq >> - modify condition checking >> - bkops_en is assigned ext_csd[EXT_CSD_BKOPS_EN] instead of "1" >> - remove the unused code >> - change pr_debug instead of pr_warn in mmc_send_hpi_cmd >> - Add the Future consideration suggested by Per >> >> Changelog V2: >> - Use EXCEPTION_STATUS instead of URGENT_BKOPS >> - Add function to check Exception_status(for eMMC4.5) >> - remove unnecessary code. >> > > The main problem with bkops is: > > If the status is at level 3 ("critical"), some operations > may extend beyond their original timeouts due to maintenance > operations which cannot be delayed anymore. > > This means: > > 1. at level 3 either bkops are run or the timeout of the next > (data?) operation is extended > > 2. at level 3 either the bkops must not be interrupted or the > level must be rechecked after interruption and bkops run again > if the level is still 3 Thanks for your comment..I will consider to solve this problem. Best Regards, Jaehoon Chung > -- > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] mmc: support BKOPS feature for eMMC
On 17/11/11 02:50, Jaehoon Chung wrote: > Enable eMMC background operations (BKOPS) feature. > > If URGENT_BKOPS is set after a response, note that BKOPS > are required. After all I/O requests are finished, run > BKOPS if required. Should read/write operations be requested > during BKOPS, first issue HPI to interrupt the ongoing BKOPS > and then service the request. > > If you want to enable this feature, set MMC_CAP2_BKOPS. > > Future considerations > * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner. > * Interrupt ongoing BKOPS before powering off the card. > > Signed-off-by: Jaehoon Chung > Signed-off-by: Kyungmin Park > CC: Hanumath Prasad > --- > Changelog V3: > - move the bkops setting's location in mmc_blk_issue_rw_rq > - modify condition checking > - bkops_en is assigned ext_csd[EXT_CSD_BKOPS_EN] instead of "1" > - remove the unused code > - change pr_debug instead of pr_warn in mmc_send_hpi_cmd > - Add the Future consideration suggested by Per > > Changelog V2: > - Use EXCEPTION_STATUS instead of URGENT_BKOPS > - Add function to check Exception_status(for eMMC4.5) > - remove unnecessary code. > The main problem with bkops is: If the status is at level 3 ("critical"), some operations may extend beyond their original timeouts due to maintenance operations which cannot be delayed anymore. This means: 1. at level 3 either bkops are run or the timeout of the next (data?) operation is extended 2. at level 3 either the bkops must not be interrupted or the level must be rechecked after interruption and bkops run again if the level is still 3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] mmc: support BKOPS feature for eMMC
Hi Jaehoon, > > i didn't know how poll for ack from card..did you know? > So i implemented that send the hpi command whatever status. > > If let me know checking for ack from card, i will consider that. Some of MMC controllers (in my case msm_sdcc) can process automatically "busy line" and fire interrupt with "prog done" bit asserted, so we can use handler of this irq to turn off "doing bkops" flag. Otherwise it is possible to read mmc controller status and check busy line, in case it is already released we can skip HPI command. Thanks, Kostya -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] mmc: support BKOPS feature for eMMC
Hi Konstantin On 11/22/2011 09:44 PM, Konstantin Dorfman wrote: > Hello Jaehoon, > > ... >> +/** >> + * mmc_start_bkops - start BKOPS for supported cards >> + * @card: MMC card to start BKOPS >> + * >> + * Start background operations whenever requested. >> + * when the urgent BKOPS bit is set in a R1 command response >> + * then background operations should be started immediately. >> +*/ >> +void mmc_start_bkops(struct mmc_card *card) >> +{ >> +int err; >> +unsigned long flags; >> + >> +BUG_ON(!card); >> +if ((!card->ext_csd.bkops_en) || >> +!(card->host->caps2 & MMC_CAP2_BKOPS)) >> +return; >> + >> +/* >> + * If card is already doing bkops or need for >> + * bkops flag is not set, then do nothing just >> + * return >> + */ >> +if (mmc_card_doing_bkops(card) >> +|| !mmc_card_need_bkops(card)) >> +return; >> + >> +mmc_claim_host(card->host); >> +err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, >> +EXT_CSD_BKOPS_START, 1, 0); >> +if (err) { >> +pr_warning("error %d starting bkops\n", err); >> +mmc_card_clr_need_bkops(card); >> +goto out; >> +} >> +spin_lock_irqsave(&card->host->lock, flags); >> +mmc_card_clr_need_bkops(card); >> +mmc_card_set_doing_bkops(card); > Sending CMD6 (by mmc_switch()) will start BKOPS on card, > according to eMMC spec: > - > 7.4.56 BKOPS_START [164] > Writing any value to this field shall manually start background operations. > Device shall stay busy till no more background operations are needed. > - > Where/when mmc_card_clear_doing_bkops() should called? The only place I > see this happens is > in mmc_interrupt_bkops(). This means, that once BKOPS started, next > read/write request > will _always_(and not when card really busy) send HPI and only then will > clear "doing" flag. Right, that is called only in mmc_interrupt_bkops. I wonder how did you check to finish the bkops without hpi command? > May be it is possible to poll for ack from card about when BKOPS finished? > Another possibility that > mmc_switch() synchronous and after flow returns from it, we can clear > "doing" flag immediately. > Does it make sense? i didn't know how poll for ack from card..did you know? So i implemented that send the hpi command whatever status. If let me know checking for ack from card, i will consider that. Thanks Best Regards, Jaehoon Chung -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] mmc: support BKOPS feature for eMMC
> Hello Jaehoon, > > ... >> +/** >> + * mmc_start_bkops - start BKOPS for supported cards >> + * @card: MMC card to start BKOPS >> + * >> + * Start background operations whenever requested. >> + * when the urgent BKOPS bit is set in a R1 command response >> + * then background operations should be started immediately. >> +*/ >> +void mmc_start_bkops(struct mmc_card *card) >> +{ >> +int err; >> +unsigned long flags; >> + >> +BUG_ON(!card); >> +if ((!card->ext_csd.bkops_en) || >> +!(card->host->caps2 & MMC_CAP2_BKOPS)) >> +return; >> + >> +/* >> + * If card is already doing bkops or need for >> + * bkops flag is not set, then do nothing just >> + * return >> + */ >> +if (mmc_card_doing_bkops(card) >> +|| !mmc_card_need_bkops(card)) >> +return; >> + >> +mmc_claim_host(card->host); >> +err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, >> +EXT_CSD_BKOPS_START, 1, 0); >> +if (err) { >> +pr_warning("error %d starting bkops\n", err); >> +mmc_card_clr_need_bkops(card); >> +goto out; >> +} >> +spin_lock_irqsave(&card->host->lock, flags); >> +mmc_card_clr_need_bkops(card); >> +mmc_card_set_doing_bkops(card); > Sending CMD6 (by mmc_switch()) will start BKOPS on card, > according to eMMC spec: > - > 7.4.56 BKOPS_START [164] > Writing any value to this field shall manually start background > operations. > Device shall stay busy till no more background operations are needed. > - > Where/when mmc_card_clear_doing_bkops() should called? The only place I > see this happens is > in mmc_interrupt_bkops(). This means, that once BKOPS started, next > read/write request > will _always_(and not when card really busy) send HPI and only then will > clear "doing" flag. > > May be it is possible to poll for ack from card about when BKOPS finished? > Another possibility that > mmc_switch() synchronous and after flow returns from it, we can clear > "doing" flag immediately. > Does it make sense? > ... Now I understand that mmc_switch() command was modified for BKOPS_START to be non-blocking, so the flow never waits for BKOPS to be finished. Because of this HPI is always sent before next request. Since start bkops flow is not frequent, it is ok. Thanks, Kostya >> +spin_unlock_irqrestore(&card->host->lock, flags); >> +out: >> +mmc_release_host(card->host); >> +} >> +EXPORT_SYMBOL(mmc_start_bkops); >> + > > Thanks, > Kostya > > -- > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] mmc: support BKOPS feature for eMMC
Hello Jaehoon, ... > +/** > + * mmc_start_bkops - start BKOPS for supported cards > + * @card: MMC card to start BKOPS > + * > + * Start background operations whenever requested. > + * when the urgent BKOPS bit is set in a R1 command response > + * then background operations should be started immediately. > +*/ > +void mmc_start_bkops(struct mmc_card *card) > +{ > + int err; > + unsigned long flags; > + > + BUG_ON(!card); > + if ((!card->ext_csd.bkops_en) || > + !(card->host->caps2 & MMC_CAP2_BKOPS)) > + return; > + > + /* > + * If card is already doing bkops or need for > + * bkops flag is not set, then do nothing just > + * return > + */ > + if (mmc_card_doing_bkops(card) > + || !mmc_card_need_bkops(card)) > + return; > + > + mmc_claim_host(card->host); > + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, > + EXT_CSD_BKOPS_START, 1, 0); > + if (err) { > + pr_warning("error %d starting bkops\n", err); > + mmc_card_clr_need_bkops(card); > + goto out; > + } > + spin_lock_irqsave(&card->host->lock, flags); > + mmc_card_clr_need_bkops(card); > + mmc_card_set_doing_bkops(card); Sending CMD6 (by mmc_switch()) will start BKOPS on card, according to eMMC spec: - 7.4.56 BKOPS_START [164] Writing any value to this field shall manually start background operations. Device shall stay busy till no more background operations are needed. - Where/when mmc_card_clear_doing_bkops() should called? The only place I see this happens is in mmc_interrupt_bkops(). This means, that once BKOPS started, next read/write request will _always_(and not when card really busy) send HPI and only then will clear "doing" flag. May be it is possible to poll for ack from card about when BKOPS finished? Another possibility that mmc_switch() synchronous and after flow returns from it, we can clear "doing" flag immediately. Does it make sense? ... > + spin_unlock_irqrestore(&card->host->lock, flags); > +out: > + mmc_release_host(card->host); > +} > +EXPORT_SYMBOL(mmc_start_bkops); > + Thanks, Kostya -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] mmc: support BKOPS feature for eMMC
Hi Konstantin, On Sun, Nov 20, 2011 at 5:12 PM, Konstantin Dorfman wrote: > Hello Per, > >> On Thu, Nov 17, 2011 at 4:01 PM, Konstantin Dorfman >> wrote: >>> Hello Jaenhoon, >>> >>> I have a few suggestions regarding the situation when Host starts BKOPS: >>> >>> 1) Host should start BKOPS (based on BKOPS_STATUS or URGENT_BKOPS event) >>> when going to mmc_sleep, which means that the bus is in idle state (this >>> also covers the case in mmc_queue_thread, because in this case no I/O >>> request exists). It seems like checking the status periodically in >>> addition >>> to mmc_suspend is not needed. Since if the device was in idle and we >>> performed a single BKOPS then there is no point in performing another >>> BKOPS >>> unless there was actually another I/O request. >>> >>> 2) Also this implies an answer to the question about need to interrupt >>> BKOPS >>> before powering off card - the answer is no. >> By the answer no you mean there is no risk of data corruption if >> cutting power in the middle of a BKOPS. When the card is powered up >> next time it will verify that bkops is in a defined state, and do >> recovery if necessary. An interesting comment I got from Sebastian is >> if this recovery mechanism affects card boot time. >> The question is: May the card boot up slower (due to recovery) next >> time if BKOPS was ongoing at power off? >> I assume this recovery time should be insignificant, but I don't know for >> sure. >> > Let me explain proposed flow: > The only trigger to start BKOPS command should be mmc_power_off() function, > just before sending POWER_OFF_NOTIFICATION[34] and only when BKOPS is needed > (by needed I understand situation, when URGENT_BKOPS event arrived or > BKOPS_STATUS 0x2 or 0x3). > The flow will wait till BKOPS successfully completed and than continue to > powering off the card. Power off will never occur in the middle of BKOPS. > Also do not need to start BKOPS when mmc_queue_thread() is in IDLE state > (no requests exists), because in such case power off should be done to card. > I wonder how this works with suspend. If suspend is called on the system, MMC should suspend quickly and not wait for the BKOPS to finish. For pm_runtime_suspend it's fine to return -EBUSY and defer pm_runtime_suspend until BKOPS is completed. mmc_power_on/off is too low level I think. What about adding this at the suspend/resume level instead? >>> 3) Based on statistical data we have (day long test) it looks like we do >>> not >>> need to do any preventive BKOPS caused by BKOPS_STATUS less than >>> critical >>> (0x3). >> I proposed this "preventive action" but at that time I didn't have any >> data to back it up with. I've run some day long tests and what I could >> see is when BKOPS_LEVEL goes from 0 to 1, it goes back to 0 without >> having to start BKOPS. Can you confirm this with your tests as well? >> One explanation I got for this is that level of 1 only means the eMMC >> internal cache is fragmented and not the actual memory. > We have such data from card vendors, but I plan to do similar tests to > confirm. > I will update about the results. Looking forward to see your results. Thanks, Per -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] mmc: support BKOPS feature for eMMC
Hello Per, > On Thu, Nov 17, 2011 at 4:01 PM, Konstantin Dorfman > wrote: >> Hello Jaenhoon, >> >> I have a few suggestions regarding the situation when Host starts BKOPS: >> >> 1) Host should start BKOPS (based on BKOPS_STATUS or URGENT_BKOPS event) >> when going to mmc_sleep, which means that the bus is in idle state (this >> also covers the case in mmc_queue_thread, because in this case no I/O >> request exists). It seems like checking the status periodically in >> addition >> to mmc_suspend is not needed. Since if the device was in idle and we >> performed a single BKOPS then there is no point in performing another >> BKOPS >> unless there was actually another I/O request. >> >> 2) Also this implies an answer to the question about need to interrupt >> BKOPS >> before powering off card - the answer is no. > By the answer no you mean there is no risk of data corruption if > cutting power in the middle of a BKOPS. When the card is powered up > next time it will verify that bkops is in a defined state, and do > recovery if necessary. An interesting comment I got from Sebastian is > if this recovery mechanism affects card boot time. > The question is: May the card boot up slower (due to recovery) next > time if BKOPS was ongoing at power off? > I assume this recovery time should be insignificant, but I don't know for > sure. > Let me explain proposed flow: The only trigger to start BKOPS command should be mmc_power_off() function, just before sending POWER_OFF_NOTIFICATION[34] and only when BKOPS is needed (by needed I understand situation, when URGENT_BKOPS event arrived or BKOPS_STATUS 0x2 or 0x3). The flow will wait till BKOPS successfully completed and than continue to powering off the card. Power off will never occur in the middle of BKOPS. Also do not need to start BKOPS when mmc_queue_thread() is in IDLE state (no requests exists), because in such case power off should be done to card. >> 3) Based on statistical data we have (day long test) it looks like we do >> not >> need to do any preventive BKOPS caused by BKOPS_STATUS less than >> critical >> (0x3). > I proposed this "preventive action" but at that time I didn't have any > data to back it up with. I've run some day long tests and what I could > see is when BKOPS_LEVEL goes from 0 to 1, it goes back to 0 without > having to start BKOPS. Can you confirm this with your tests as well? > One explanation I got for this is that level of 1 only means the eMMC > internal cache is fragmented and not the actual memory. We have such data from card vendors, but I plan to do similar tests to confirm. I will update about the results. Thanks, Kostya > > Thanks, > Per > >> -Original Message- >> From: linux-mmc-ow...@vger.kernel.org >> [mailto:linux-mmc-ow...@vger.kernel.org] On Behalf Of Jaehoon Chung >> Sent: Thursday, November 17, 2011 2:50 AM >> To: linux-mmc >> Cc: Chris Ball; Kyungmin Park; Hanumath Prasad; Per Forlin; Sebastian >> Rasmussen; Dong, Chuanxiao; svenk...@ti.com >> Subject: [PATCH v3] mmc: support BKOPS feature for eMMC >> >> Enable eMMC background operations (BKOPS) feature. >> >> If URGENT_BKOPS is set after a response, note that BKOPS >> are required. After all I/O requests are finished, run >> BKOPS if required. Should read/write operations be requested >> during BKOPS, first issue HPI to interrupt the ongoing BKOPS >> and then service the request. >> >> If you want to enable this feature, set MMC_CAP2_BKOPS. >> >> Future considerations >> * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner. >> * Interrupt ongoing BKOPS before powering off the card. >> >> Signed-off-by: Jaehoon Chung >> Signed-off-by: Kyungmin Park >> CC: Hanumath Prasad >> --- >> Changelog V3: >> - move the bkops setting's location in mmc_blk_issue_rw_rq >> - modify condition checking >> - bkops_en is assigned ext_csd[EXT_CSD_BKOPS_EN] instead of "1" >> - remove the unused code >> - change pr_debug instead of pr_warn in mmc_send_hpi_cmd >> - Add the Future consideration suggested by Per >> >> Changelog V2: >> - Use EXCEPTION_STATUS instead of URGENT_BKOPS >> - Add function to check Exception_status(for eMMC4.5) >> - remove unnecessary code. >> >> drivers/mmc/card/block.c | 10 + >> drivers/mmc/card/queue.c | 4 ++ >> drivers/mmc/core/core.c | 87 >> >> drivers/mmc/core/mmc.c | 8 >> drivers/mmc/cor
Re: [PATCH v3] mmc: support BKOPS feature for eMMC
On Thu, Nov 17, 2011 at 4:01 PM, Konstantin Dorfman wrote: > Hello Jaenhoon, > > I have a few suggestions regarding the situation when Host starts BKOPS: > > 1) Host should start BKOPS (based on BKOPS_STATUS or URGENT_BKOPS event) > when going to mmc_sleep, which means that the bus is in idle state (this > also covers the case in mmc_queue_thread, because in this case no I/O > request exists). It seems like checking the status periodically in addition > to mmc_suspend is not needed. Since if the device was in idle and we > performed a single BKOPS then there is no point in performing another BKOPS > unless there was actually another I/O request. > > 2) Also this implies an answer to the question about need to interrupt BKOPS > before powering off card - the answer is no. By the answer no you mean there is no risk of data corruption if cutting power in the middle of a BKOPS. When the card is powered up next time it will verify that bkops is in a defined state, and do recovery if necessary. An interesting comment I got from Sebastian is if this recovery mechanism affects card boot time. The question is: May the card boot up slower (due to recovery) next time if BKOPS was ongoing at power off? I assume this recovery time should be insignificant, but I don't know for sure. > 3) Based on statistical data we have (day long test) it looks like we do not > need to do any preventive BKOPS caused by BKOPS_STATUS less than critical > (0x3). I proposed this "preventive action" but at that time I didn't have any data to back it up with. I've run some day long tests and what I could see is when BKOPS_LEVEL goes from 0 to 1, it goes back to 0 without having to start BKOPS. Can you confirm this with your tests as well? One explanation I got for this is that level of 1 only means the eMMC internal cache is fragmented and not the actual memory. Thanks, Per > -Original Message- > From: linux-mmc-ow...@vger.kernel.org > [mailto:linux-mmc-ow...@vger.kernel.org] On Behalf Of Jaehoon Chung > Sent: Thursday, November 17, 2011 2:50 AM > To: linux-mmc > Cc: Chris Ball; Kyungmin Park; Hanumath Prasad; Per Forlin; Sebastian > Rasmussen; Dong, Chuanxiao; svenk...@ti.com > Subject: [PATCH v3] mmc: support BKOPS feature for eMMC > > Enable eMMC background operations (BKOPS) feature. > > If URGENT_BKOPS is set after a response, note that BKOPS > are required. After all I/O requests are finished, run > BKOPS if required. Should read/write operations be requested > during BKOPS, first issue HPI to interrupt the ongoing BKOPS > and then service the request. > > If you want to enable this feature, set MMC_CAP2_BKOPS. > > Future considerations > * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner. > * Interrupt ongoing BKOPS before powering off the card. > > Signed-off-by: Jaehoon Chung > Signed-off-by: Kyungmin Park > CC: Hanumath Prasad > --- > Changelog V3: > - move the bkops setting's location in mmc_blk_issue_rw_rq > - modify condition checking > - bkops_en is assigned ext_csd[EXT_CSD_BKOPS_EN] instead of "1" > - remove the unused code > - change pr_debug instead of pr_warn in mmc_send_hpi_cmd > - Add the Future consideration suggested by Per > > Changelog V2: > - Use EXCEPTION_STATUS instead of URGENT_BKOPS > - Add function to check Exception_status(for eMMC4.5) > - remove unnecessary code. > > drivers/mmc/card/block.c | 10 + > drivers/mmc/card/queue.c | 4 ++ > drivers/mmc/core/core.c | 87 > > drivers/mmc/core/mmc.c | 8 > drivers/mmc/core/mmc_ops.c | 6 +++- > include/linux/mmc/card.h | 12 ++ > include/linux/mmc/core.h | 3 ++ > include/linux/mmc/host.h | 1 + > include/linux/mmc/mmc.h | 14 +++ > 9 files changed, 144 insertions(+), 1 deletions(-) > > diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c > index c80bb6d..9d19ebb 100644 > --- a/drivers/mmc/card/block.c > +++ b/drivers/mmc/card/block.c > @@ -1188,6 +1188,16 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, > struct request *rqc) > type = rq_data_dir(req) == READ ? MMC_BLK_READ : > MMC_BLK_WRITE; > mmc_queue_bounce_post(mq_rq); > > + /* > + * Check BKOPS urgency from each R1 response > + */ > + if (mmc_card_mmc(card) && > + (brq->cmd.resp[0] & R1_EXCEPTION_EVENT)) { > + if (mmc_is_exception_event(card, > + EXT_CSD_URGENT_BKOPS)) > + mmc_card_set_nee
RE: [PATCH v3] mmc: support BKOPS feature for eMMC
Hello Jaenhoon, I have a few suggestions regarding the situation when Host starts BKOPS: 1) Host should start BKOPS (based on BKOPS_STATUS or URGENT_BKOPS event) when going to mmc_sleep, which means that the bus is in idle state (this also covers the case in mmc_queue_thread, because in this case no I/O request exists). It seems like checking the status periodically in addition to mmc_suspend is not needed. Since if the device was in idle and we performed a single BKOPS then there is no point in performing another BKOPS unless there was actually another I/O request. 2) Also this implies an answer to the question about need to interrupt BKOPS before powering off card - the answer is no. 3) Based on statistical data we have (day long test) it looks like we do not need to do any preventive BKOPS caused by BKOPS_STATUS less than critical (0x3). Thanks, Konstantin Dorfman Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum -Original Message- From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-ow...@vger.kernel.org] On Behalf Of Jaehoon Chung Sent: Thursday, November 17, 2011 2:50 AM To: linux-mmc Cc: Chris Ball; Kyungmin Park; Hanumath Prasad; Per Forlin; Sebastian Rasmussen; Dong, Chuanxiao; svenk...@ti.com Subject: [PATCH v3] mmc: support BKOPS feature for eMMC Enable eMMC background operations (BKOPS) feature. If URGENT_BKOPS is set after a response, note that BKOPS are required. After all I/O requests are finished, run BKOPS if required. Should read/write operations be requested during BKOPS, first issue HPI to interrupt the ongoing BKOPS and then service the request. If you want to enable this feature, set MMC_CAP2_BKOPS. Future considerations * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner. * Interrupt ongoing BKOPS before powering off the card. Signed-off-by: Jaehoon Chung Signed-off-by: Kyungmin Park CC: Hanumath Prasad --- Changelog V3: - move the bkops setting's location in mmc_blk_issue_rw_rq - modify condition checking - bkops_en is assigned ext_csd[EXT_CSD_BKOPS_EN] instead of "1" - remove the unused code - change pr_debug instead of pr_warn in mmc_send_hpi_cmd - Add the Future consideration suggested by Per Changelog V2: - Use EXCEPTION_STATUS instead of URGENT_BKOPS - Add function to check Exception_status(for eMMC4.5) - remove unnecessary code. drivers/mmc/card/block.c | 10 + drivers/mmc/card/queue.c |4 ++ drivers/mmc/core/core.c| 87 drivers/mmc/core/mmc.c |8 drivers/mmc/core/mmc_ops.c |6 +++- include/linux/mmc/card.h | 12 ++ include/linux/mmc/core.h |3 ++ include/linux/mmc/host.h |1 + include/linux/mmc/mmc.h| 14 +++ 9 files changed, 144 insertions(+), 1 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index c80bb6d..9d19ebb 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1188,6 +1188,16 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) type = rq_data_dir(req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE; mmc_queue_bounce_post(mq_rq); + /* +* Check BKOPS urgency from each R1 response +*/ + if (mmc_card_mmc(card) && + (brq->cmd.resp[0] & R1_EXCEPTION_EVENT)) { + if (mmc_is_exception_event(card, + EXT_CSD_URGENT_BKOPS)) + mmc_card_set_need_bkops(card); + } + switch (status) { case MMC_BLK_SUCCESS: case MMC_BLK_PARTIAL: diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index dcad59c..20bb4a5 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -61,6 +61,9 @@ static int mmc_queue_thread(void *d) spin_unlock_irq(q->queue_lock); if (req || mq->mqrq_prev->req) { + if (mmc_card_doing_bkops(mq->card)) + mmc_interrupt_bkops(mq->card); + set_current_state(TASK_RUNNING); mq->issue_fn(mq, req); } else { @@ -68,6 +71,7 @@ static int mmc_queue_thread(void *d) set_current_state(TASK_RUNNING); break; } + mmc_start_bkops(mq->card); up(&mq->thread_sem); schedule(); down(&mq->thread_sem); diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 7ee2e07..2d2f1d5 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -238,6 +238,50 @@ mmc_start_request(struct mmc_host *ho
Re: [PATCH v3] mmc: support BKOPS feature for eMMC
On Thu, Nov 17, 2011 at 6:20 AM, Jaehoon Chung wrote: > Enable eMMC background operations (BKOPS) feature. > > If URGENT_BKOPS is set after a response, note that BKOPS > are required. After all I/O requests are finished, run > BKOPS if required. Should read/write operations be requested > during BKOPS, first issue HPI to interrupt the ongoing BKOPS > and then service the request. > > If you want to enable this feature, set MMC_CAP2_BKOPS. > > Future considerations > * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner. > * Interrupt ongoing BKOPS before powering off the card. > > Signed-off-by: Jaehoon Chung > Signed-off-by: Kyungmin Park > CC: Hanumath Prasad > --- > Changelog V3: > - move the bkops setting's location in mmc_blk_issue_rw_rq > - modify condition checking > - bkops_en is assigned ext_csd[EXT_CSD_BKOPS_EN] instead of "1" > - remove the unused code > - change pr_debug instead of pr_warn in mmc_send_hpi_cmd > - Add the Future consideration suggested by Per > > Changelog V2: > - Use EXCEPTION_STATUS instead of URGENT_BKOPS > - Add function to check Exception_status(for eMMC4.5) > - remove unnecessary code. > > drivers/mmc/card/block.c | 10 + > drivers/mmc/card/queue.c | 4 ++ > drivers/mmc/core/core.c | 87 > > drivers/mmc/core/mmc.c | 8 > drivers/mmc/core/mmc_ops.c | 6 +++- > include/linux/mmc/card.h | 12 ++ > include/linux/mmc/core.h | 3 ++ > include/linux/mmc/host.h | 1 + > include/linux/mmc/mmc.h | 14 +++ > 9 files changed, 144 insertions(+), 1 deletions(-) > > diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c > index c80bb6d..9d19ebb 100644 > --- a/drivers/mmc/card/block.c > +++ b/drivers/mmc/card/block.c > @@ -1188,6 +1188,16 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, > struct request *rqc) > type = rq_data_dir(req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE; > mmc_queue_bounce_post(mq_rq); > > + /* > + * Check BKOPS urgency from each R1 response > + */ > + if (mmc_card_mmc(card) && > + (brq->cmd.resp[0] & R1_EXCEPTION_EVENT)) { > + if (mmc_is_exception_event(card, > + EXT_CSD_URGENT_BKOPS)) > + mmc_card_set_need_bkops(card); > + } > + > switch (status) { > case MMC_BLK_SUCCESS: > case MMC_BLK_PARTIAL: > diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c > index dcad59c..20bb4a5 100644 > --- a/drivers/mmc/card/queue.c > +++ b/drivers/mmc/card/queue.c > @@ -61,6 +61,9 @@ static int mmc_queue_thread(void *d) > spin_unlock_irq(q->queue_lock); > > if (req || mq->mqrq_prev->req) { > + if (mmc_card_doing_bkops(mq->card)) > + mmc_interrupt_bkops(mq->card); Should you interrupt bkops for any request or just for read /write requests ? > + > set_current_state(TASK_RUNNING); > mq->issue_fn(mq, req); > } else { > @@ -68,6 +71,7 @@ static int mmc_queue_thread(void *d) > set_current_state(TASK_RUNNING); > break; > } > + mmc_start_bkops(mq->card); > up(&mq->thread_sem); > schedule(); > down(&mq->thread_sem); > diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c > index 7ee2e07..2d2f1d5 100644 > --- a/drivers/mmc/core/core.c > +++ b/drivers/mmc/core/core.c > @@ -238,6 +238,50 @@ mmc_start_request(struct mmc_host *host, struct > mmc_request *mrq) > host->ops->request(host, mrq); > } > > +/** > + * mmc_start_bkops - start BKOPS for supported cards > + * @card: MMC card to start BKOPS > + * > + * Start background operations whenever requested. > + * when the urgent BKOPS bit is set in a R1 command response > + * then background operations should be started immediately. > +*/ > +void mmc_start_bkops(struct mmc_card *card) > +{ > + int err; > + unsigned long flags; > + > + BUG_ON(!card); > + if ((!card->ext_csd.bkops_en) || > + !(card->host->caps2 & MMC_CAP2_BKOPS)) > + return; > + > + /* > + * If card is already doing bkops or need for > + * bkops flag is not set, then do nothing just > + * return > + */ > + if (mmc_card_doing_bkops(card) > + || !mmc_card_need_bkops(card)) > + return; > + > + mmc_claim_host(card->host); > + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, > + EXT_CSD_BKOPS_START, 1, 0); > +
[PATCH v3] mmc: support BKOPS feature for eMMC
Enable eMMC background operations (BKOPS) feature. If URGENT_BKOPS is set after a response, note that BKOPS are required. After all I/O requests are finished, run BKOPS if required. Should read/write operations be requested during BKOPS, first issue HPI to interrupt the ongoing BKOPS and then service the request. If you want to enable this feature, set MMC_CAP2_BKOPS. Future considerations * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner. * Interrupt ongoing BKOPS before powering off the card. Signed-off-by: Jaehoon Chung Signed-off-by: Kyungmin Park CC: Hanumath Prasad --- Changelog V3: - move the bkops setting's location in mmc_blk_issue_rw_rq - modify condition checking - bkops_en is assigned ext_csd[EXT_CSD_BKOPS_EN] instead of "1" - remove the unused code - change pr_debug instead of pr_warn in mmc_send_hpi_cmd - Add the Future consideration suggested by Per Changelog V2: - Use EXCEPTION_STATUS instead of URGENT_BKOPS - Add function to check Exception_status(for eMMC4.5) - remove unnecessary code. drivers/mmc/card/block.c | 10 + drivers/mmc/card/queue.c |4 ++ drivers/mmc/core/core.c| 87 drivers/mmc/core/mmc.c |8 drivers/mmc/core/mmc_ops.c |6 +++- include/linux/mmc/card.h | 12 ++ include/linux/mmc/core.h |3 ++ include/linux/mmc/host.h |1 + include/linux/mmc/mmc.h| 14 +++ 9 files changed, 144 insertions(+), 1 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index c80bb6d..9d19ebb 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1188,6 +1188,16 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) type = rq_data_dir(req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE; mmc_queue_bounce_post(mq_rq); + /* +* Check BKOPS urgency from each R1 response +*/ + if (mmc_card_mmc(card) && + (brq->cmd.resp[0] & R1_EXCEPTION_EVENT)) { + if (mmc_is_exception_event(card, + EXT_CSD_URGENT_BKOPS)) + mmc_card_set_need_bkops(card); + } + switch (status) { case MMC_BLK_SUCCESS: case MMC_BLK_PARTIAL: diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index dcad59c..20bb4a5 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -61,6 +61,9 @@ static int mmc_queue_thread(void *d) spin_unlock_irq(q->queue_lock); if (req || mq->mqrq_prev->req) { + if (mmc_card_doing_bkops(mq->card)) + mmc_interrupt_bkops(mq->card); + set_current_state(TASK_RUNNING); mq->issue_fn(mq, req); } else { @@ -68,6 +71,7 @@ static int mmc_queue_thread(void *d) set_current_state(TASK_RUNNING); break; } + mmc_start_bkops(mq->card); up(&mq->thread_sem); schedule(); down(&mq->thread_sem); diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 7ee2e07..2d2f1d5 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -238,6 +238,50 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) host->ops->request(host, mrq); } +/** + * mmc_start_bkops - start BKOPS for supported cards + * @card: MMC card to start BKOPS + * + * Start background operations whenever requested. + * when the urgent BKOPS bit is set in a R1 command response + * then background operations should be started immediately. +*/ +void mmc_start_bkops(struct mmc_card *card) +{ + int err; + unsigned long flags; + + BUG_ON(!card); + if ((!card->ext_csd.bkops_en) || + !(card->host->caps2 & MMC_CAP2_BKOPS)) + return; + + /* +* If card is already doing bkops or need for +* bkops flag is not set, then do nothing just +* return +*/ + if (mmc_card_doing_bkops(card) + || !mmc_card_need_bkops(card)) + return; + + mmc_claim_host(card->host); + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BKOPS_START, 1, 0); + if (err) { + pr_warning("error %d starting bkops\n", err); + mmc_card_clr_need_bkops(card); + goto out; + } + spin_lock_irqsave(&card->host->lock, flags); + mmc_card_clr_need_bkops(card); + mmc_card_set_doing_bkops(card); + spin_unlock_irqrestore(&card->host->lock, f