Re: [PATCH] mmc: tmio: fix recursive spinlock, don't schedule with interrupts disabled

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 15 Jun 2011, Guennadi Liakhovetski wrote:

> Calling mmc_request_done() under a spinlock with interrupts disabled
> leads to a recursive spin-lock on request retry path and to
> scheduling in atomic context. This patch fixes both these problems
> by moving mmc_request_done() to the scheduler workqueue.

Hm, sorry, please, wait with this one, I have to test it a bit more.

Thanks
Guennadi

> 
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@xxxxxx>
> ---
> 
> Morimoto-san, this should fix the race in TMIO / SDHI driver, that you 
> reported here:
> 
> http://article.gmane.org/gmane.linux.ports.sh.devel/11349
> 
> Please, verify.
> 
>  drivers/mmc/host/tmio_mmc.h     |    2 ++
>  drivers/mmc/host/tmio_mmc_pio.c |   14 +++++++++++---
>  2 files changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
> index 8260bc2..b4dfc13 100644
> --- a/drivers/mmc/host/tmio_mmc.h
> +++ b/drivers/mmc/host/tmio_mmc.h
> @@ -73,6 +73,8 @@ struct tmio_mmc_host {
>  
>  	/* Track lost interrupts */
>  	struct delayed_work	delayed_reset_work;
> +	struct work_struct	done;
> +	/* protect host private data */
>  	spinlock_t		lock;
>  	unsigned long		last_req_ts;
>  };
> diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
> index ad6347b..1b63045 100644
> --- a/drivers/mmc/host/tmio_mmc_pio.c
> +++ b/drivers/mmc/host/tmio_mmc_pio.c
> @@ -297,10 +297,16 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host)
>  
>  	host->mrq = NULL;
>  
> -	/* FIXME: mmc_request_done() can schedule! */
>  	mmc_request_done(host->mmc, mrq);
>  }
>  
> +static void tmio_mmc_done_work(struct work_struct *work)
> +{
> +	struct tmio_mmc_host *host = container_of(work, struct tmio_mmc_host,
> +						  done);
> +	tmio_mmc_finish_request(host);
> +}
> +
>  /* These are the bitmasks the tmio chip requires to implement the MMC response
>   * types. Note that R1 and R6 are the same in this scheme. */
>  #define APP_CMD        0x0040
> @@ -467,7 +473,7 @@ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host)
>  			BUG();
>  	}
>  
> -	tmio_mmc_finish_request(host);
> +	schedule_work(&host->done);
>  }
>  
>  static void tmio_mmc_data_irq(struct tmio_mmc_host *host)
> @@ -557,7 +563,7 @@ static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host,
>  				tasklet_schedule(&host->dma_issue);
>  		}
>  	} else {
> -		tmio_mmc_finish_request(host);
> +		schedule_work(&host->done);
>  	}
>  
>  out:
> @@ -916,6 +922,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
>  
>  	/* Init delayed work for request timeouts */
>  	INIT_DELAYED_WORK(&_host->delayed_reset_work, tmio_mmc_reset_work);
> +	INIT_WORK(&_host->done, tmio_mmc_done_work);
>  
>  	/* See if we also get DMA */
>  	tmio_mmc_request_dma(_host, pdata);
> @@ -963,6 +970,7 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
>  		pm_runtime_get_sync(&pdev->dev);
>  
>  	mmc_remove_host(host->mmc);
> +	cancel_work_sync(&host->done);
>  	cancel_delayed_work_sync(&host->delayed_reset_work);
>  	tmio_mmc_release_dma(host);
>  
> -- 
> 1.7.2.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux