Re: [PATCH v2 21/72] ncr5380: Sleep when polling, if possible

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

 



Hi Finn,

On Sun, Dec 6, 2015 at 2:31 AM, Finn Thain <fthain@xxxxxxxxxxxxxxxxxxx> wrote:
When in process context, sleep during polling if doing so won't add
significant latency. In interrupt context or if the lock is held, poll
briefly then give up. Keep both core drivers in sync.

Calibrate busy-wait iterations to allow for variation in chip register
access times between different 5380 hardware implementations.

Signed-off-by: Finn Thain <fthain@xxxxxxxxxxxxxxxxxxx>

---

Changed since v1:
- Don't rely on loops_per_jiffy to estimate register access speed, measure
  it instead.

---
 drivers/scsi/NCR5380.c       |   77 +++++++++++++++++++++++++------------------
 drivers/scsi/NCR5380.h       |    1
 drivers/scsi/atari_NCR5380.c |   59 ++++++++++++++++++++------------
 3 files changed, 84 insertions(+), 53 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c   2015-12-06 12:29:51.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c        2015-12-06 12:29:54.000000000 +1100
@@ -293,44 +293,48 @@ static inline void initialize_SCp(struct
 }

 /**
- *     NCR5380_poll_politely   -       wait for NCR5380 status bits
- *     @instance: controller to poll
- *     @reg: 5380 register to poll
- *     @bit: Bitmask to check
- *     @val: Value required to exit
- *
- *     Polls the NCR5380 in a reasonably efficient manner waiting for
- *     an event to occur, after a short quick poll we begin giving the
- *     CPU back in non IRQ contexts
+ * NCR5380_poll_politely - wait for chip register value
+ * @instance: controller to poll
+ * @reg: 5380 register to poll
+ * @bit: Bitmask to check
+ * @val: Value required to exit
+ * @wait: Time-out in jiffies
+ *
+ * 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
+ * (if possible). In irq contexts the time-out is arbitrarily limited.
+ * Callers may hold locks as long as they are held in irq mode.
  *
- *     Returns the value of the register or a negative error code.
+ * Returns 0 if event occurred otherwise -ETIMEDOUT.
  */
-
-static int NCR5380_poll_politely(struct Scsi_Host *instance, int reg, int bit, int val, int t)
+
+static int NCR5380_poll_politely(struct Scsi_Host *instance,
+                                 int reg, int bit, int val, int wait)
 {
-       int n = 500;            /* At about 8uS a cycle for the cpu access */
-       unsigned long end = jiffies + t;
-       int r;
-
-       while( n-- > 0)
-       {
-               r = NCR5380_read(reg);
-               if((r & bit) == val)
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       unsigned long deadline = jiffies + wait;
+       unsigned long n;
+
+       /* Busy-wait for up to 10 ms */
+       n = min(10000U, jiffies_to_usecs(wait));
+       n *= hostdata->accesses_per_ms;
+       n /= 1000;
+       do {
+               if ((NCR5380_read(reg) & bit) == val)
                        return 0;
                cpu_relax();
-       }

@@ -773,6 +777,7 @@ static int NCR5380_init(struct Scsi_Host
 {
        int i;
        struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+       unsigned long deadline;

        if(in_interrupt())
                printk(KERN_ERR "NCR5380_init called with interrupts off!\n");
@@ -812,6 +817,16 @@ static int NCR5380_init(struct Scsi_Host
        NCR5380_write(MODE_REG, MR_BASE);
        NCR5380_write(TARGET_COMMAND_REG, 0);
        NCR5380_write(SELECT_ENABLE_REG, 0);
+
+       /* Calibrate register polling loop */
+       i = 0;
+       deadline = jiffies + msecs_to_jiffies(100) + 1;
+       do {
+               NCR5380_read(STATUS_REG);
+               ++i;
+       } while (time_is_after_jiffies(deadline));
+       hostdata->accesses_per_ms = i / 100;

As the caller of NCR5380_poll_politely() passes a timeout value in jiffies,
calculations may become simpler if you store the number of accesses per jiffy
instead of per ms.

Unlike the historical calibrating-delay-loop code, you don't wait for a jiffy
change before starting the calibration. At first I thought that was OK, but on
some platforms, HZ can be as low as 24, which means the result can vary by 33%
(based on 100 ms -> 3 jiffies).

The same change is made to atari_NCR5380.c.
I guess you plan to deduplicate this code when merging the drivers, i.e.
after this series?

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-m68k" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Video for Linux]     [Yosemite News]     [Linux S/390]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux