Re: [PATCH v2] scsi: NCR5380: Remove context check

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

 



On Fri, 4 Dec 2020, Ahmed S. Darwish wrote:

> NCR5380_poll_politely2() uses in_interrupt() and irqs_disabled() to
> check if it is safe to sleep.
> 
> Such usage in drivers is phased out and Linus clearly requested that
> code which changes behaviour depending on context should either be
> separated, or the context be explicitly conveyed in an argument passed
> by the caller.
> 
> Below is a context analysis of NCR5380_poll_politely2() uppermost
> callers:
> 
>   - NCR5380_maybe_reset_bus(), task, invoked during device probe.
>     -> NCR5380_poll_politely()
>     -> do_abort()
> 
>   - NCR5380_select(), task, but can only sleep in the "release, then
>     re-acquire" regions of the spinlock held by its caller.
>     Sleeping invocations (lock released):
>     -> NCR5380_poll_politely2()
> 
>     Atomic invocations (lock acquired):
>     -> NCR5380_reselect()
>        -> NCR5380_poll_politely()
>        -> do_abort()
>        -> NCR5380_transfer_pio()
> 
>   - NCR5380_intr(), interrupt handler
>     -> NCR5380_dma_complete()
>        -> NCR5380_transfer_pio()
> 	  -> NCR5380_poll_politely()
>     -> NCR5380_reselect() (see above)
> 
>   - NCR5380_information_transfer(), task, but can only sleep in the
>     "release, then re-acquire" regions of the caller-held spinlock.
>     Sleeping invocations (lock released):
>       - NCR5380_transfer_pio() -> NCR5380_poll_politely()
>       - NCR5380_poll_politely()
> 
>     Atomic invocations (lock acquired):
>       - NCR5380_transfer_dma()
> 	-> NCR5380_dma_recv_setup()
>            => generic_NCR5380_precv() -> NCR5380_poll_politely()
> 	   => macscsi_pread() -> NCR5380_poll_politely()
> 
> 	-> NCR5380_dma_send_setup()
>  	   => generic_NCR5380_psend -> NCR5380_poll_politely2()
> 	   => macscsi_pwrite() -> NCR5380_poll_politely()
> 
> 	-> NCR5380_poll_politely2()
>         -> NCR5380_dma_complete()
>            -> NCR5380_transfer_pio()
> 	      -> NCR5380_poll_politely()
>       - NCR5380_transfer_pio() -> NCR5380_poll_politely
> 
>   - NCR5380_reselect(), atomic, always called with hostdata spinlock
>     held.
> 
> Since NCR5380_poll_politely2() already takes a "wait" argument in
> jiffies, use it to determine if the function can sleep. Modify atomic
> callers, which passed an unused wait value in terms of HZ, to pass zero.
> 
> Suggested-by: Finn Thain <fthain@xxxxxxxxxxxxxxxxxxx>
> Co-developed-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
> Signed-off-by: Ahmed S. Darwish <a.darwish@xxxxxxxxxxxxx>
> Cc: Michael Schmitz <schmitzmic@xxxxxxxxx>
> Cc: <linux-m68k@xxxxxxxxxxxxxxxxxxxx>
> ---
>  drivers/scsi/NCR5380.c   | 77 ++++++++++++++++++++++------------------
>  drivers/scsi/NCR5380.h   |  3 +-
>  drivers/scsi/g_NCR5380.c | 12 +++----
>  drivers/scsi/mac_scsi.c  | 10 +++---
>  4 files changed, 55 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
> index d654a6cc4162..60200f61592e 100644
> --- a/drivers/scsi/NCR5380.c
> +++ b/drivers/scsi/NCR5380.c
> @@ -132,7 +132,7 @@
>  static unsigned int disconnect_mask = ~0;
>  module_param(disconnect_mask, int, 0444);
>  
> -static int do_abort(struct Scsi_Host *);
> +static int do_abort(struct Scsi_Host *, unsigned int);
>  static void do_reset(struct Scsi_Host *);
>  static void bus_reset_cleanup(struct Scsi_Host *);
>  
> @@ -197,7 +197,7 @@ static inline void set_resid_from_SCp(struct scsi_cmnd *cmd)
>   * @reg2: Second 5380 register to poll
>   * @bit2: Second bitmask to check
>   * @val2: Second expected value
> - * @wait: Time-out in jiffies
> + * @wait: Time-out in jiffies, 0 if sleeping is not allowed
>   *
>   * Polls the chip in a reasonably efficient manner waiting for an
>   * event to occur. After a short quick poll we begin to yield the CPU
> @@ -213,7 +213,7 @@ static int NCR5380_poll_politely2(struct NCR5380_hostdata *hostdata,
>                                    unsigned long wait)
>  {
>  	unsigned long n = hostdata->poll_loops;
> -	unsigned long deadline = jiffies + wait;
> +	unsigned long deadline;
>  
>  	do {
>  		if ((NCR5380_read(reg1) & bit1) == val1)
> @@ -223,10 +223,11 @@ static int NCR5380_poll_politely2(struct NCR5380_hostdata *hostdata,
>  		cpu_relax();
>  	} while (n--);
>  
> -	if (irqs_disabled() || in_interrupt())
> +	if (!wait)
>  		return -ETIMEDOUT;
>  
>  	/* Repeatedly sleep for 1 ms until deadline */
> +	deadline = jiffies + wait;
>  	while (time_is_after_jiffies(deadline)) {
>  		schedule_timeout_uninterruptible(1);
>  		if ((NCR5380_read(reg1) & bit1) == val1)

The deadline assignment shouldn't be moved. That's a behavioural change 
and doesn't fit under the stated aim of this patch. Also, it isn't 
actually a desirable change: the argument to this function is the overall 
wait time, not just the sleep limit.

The rest looks ok.



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux