Re: direct-to-BIO for O_DIRECT

From: Lincoln Dale (ltd@cisco.com)
Date: Thu Jul 11 2002 - 18:40:30 EST


At 12:52 PM 11/07/2002 -0700, Jesse Barnes wrote:
>On Thu, Jul 11, 2002 at 12:25:03PM +1000, Lincoln Dale wrote:
> > sorry for the delay.
> > upgrading from 2.4.19 to 2.5.25 took longer than expected, since the
> > QLogic FC 2300 HBA driver isn't part of the standard kernel, and i
> > had to update it to reflect the io_request_lock -> host->host_lock,
> > kdev_t and kbuild changes. urgh, pain pain pain. in the process, i
> > discovered some races in their driver, so fixed them also.
>
>So you ported the qla2x00 driver forward to 2.5? Would it be possible
>to post that driver? Not having it has held up some testing I'd like
>to do...

these are the changes to the qla2x00 6.1 beta 2 driver, as downloadable
from the QLogic web-site.

there were also some changes required to the makefiles to get this working
with linux-2.5 kbuild infrastructure.
the hacks i did there are awful and i'm not prepared to put my name against
those bad hacks just yet. :-)

===
diff -urN base/listops.h 2.5.25/listops.h
--- base/listops.h Tue Apr 16 05:15:40 2002
+++ 2.5.25/listops.h Fri Jul 12 09:29:45 2002
@@ -324,9 +324,9 @@
                  return;
          }

- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(ha->host->host_lock, flags);
          qla2x00_callback(ha, sp->cmd);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(ha->host->host_lock, flags);
  }

  /**************************************************************************
diff -urN base/qla2x00.c 2.5.25/qla2x00.c
--- base/qla2x00.c Wed Jul 10 18:32:25 2002
+++ 2.5.25/qla2x00.c Fri Jul 12 09:29:51 2002
@@ -532,10 +532,11 @@
  static int recoveryTime = MAX_RECOVERYTIME;
  static int failbackTime = MAX_FAILBACKTIME;
  #endif /* end of MPIO_SUPPORT */
-#ifdef MODULE
+
  static char *ql2xopts = NULL;
  static int ql2xmaxqdepth = 0;

+#ifdef MODULE
  /* insmod qla2100 ql2xopts=verbose" */
  MODULE_PARM(ql2xopts, "s");
  MODULE_PARM(ql2xmaxqdepth, "i");
@@ -552,7 +553,6 @@
          MODULE_LICENSE("GPL");
  #endif

-#include "listops.h"
  #include "qla_fo.cfg"

@@ -564,6 +564,7 @@
  static char dummy_buffer[60] = "Please don't add commas in your insmod
command!!\n";

  #endif
+#include "listops.h"

  #if QLA2100_LIPTEST
  static int qla2x00_lip = 0;
@@ -1459,10 +1460,6 @@

         ENTER("qla2x00_detect");

-#if NEW_EH_CODE
- spin_unlock_irq(&io_request_lock);
-#endif
-
  #ifdef MODULE
         DEBUG2(printk("DEBUG: qla2x00_set_info starts at address = %p\n",
                         qla2x00_set_info);)
@@ -1497,9 +1494,6 @@

         if (!pci_present()) {
                 printk("scsi: PCI not present\n");
-#if NEW_EH_CODE
- spin_lock_irq(&io_request_lock);
-#endif
                 return 0;
         } /* end of !pci_present() */

@@ -1542,9 +1536,6 @@
                            continue;
                            }
                          */
-#if NEW_EH_CODE
- spin_lock_irq(&io_request_lock);
-#endif

                         if ((host =
                                 scsi_register(
@@ -1609,9 +1600,6 @@
                                         "scsi%d: [ERROR] Failed to allocate "
                                         "memory for adapter\n",host->host_no);
                                 qla2x00_mem_free(ha);
-#if NEW_EH_CODE
- spin_unlock_irq(&io_request_lock);
-#endif
                                 continue;
                         }

@@ -1654,10 +1642,6 @@

                         ha->list_lock = SPIN_LOCK_UNLOCKED;

-#if NEW_EH_CODE
- spin_unlock_irq(&io_request_lock);
-#endif
-
                         if (qla2x00_initialize_adapter(ha) &&
                                 !(ha->device_flags & DFLG_NO_CABLE)) {

@@ -1706,8 +1690,7 @@
                         ha->fabricid[SIMPLE_NAME_SERVER].in_use = TRUE;

  #if NEW_EH_CODE
-
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(host->host_lock);
  #endif

                         /* Register our resources with Linux */
@@ -1719,7 +1702,7 @@
                                 qla2x00_mem_free(ha);
                                 scsi_unregister(host);
  #if NEW_EH_CODE
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(host->host_lock);
  #endif
                                 continue;
                         }
@@ -1741,7 +1724,7 @@
                         spin_unlock_irqrestore(&ha->hardware_lock, flags);

  #if NEW_EH_CODE
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(host->host_lock);
  #endif

  #if MPIO_SUPPORT
@@ -1805,10 +1788,6 @@
                 }
         } /* end of FOR */

-#if NEW_EH_CODE
- spin_lock_irq(&io_request_lock);
-#endif
-
         LEAVE("qla2x00_detect");

         return num_hosts;
@@ -2217,7 +2196,7 @@
         ha = (scsi_qla_host_t *) host->hostdata;

         cmd->scsi_done = fn;
- spin_unlock(&io_request_lock);
+ spin_unlock(host->host_lock);

         /* Allocate a command packet from the "sp" pool.
          * If we cant get back one then let scsi layer
@@ -2227,7 +2206,7 @@
                 printk(KERN_WARNING
                         "queuecommand: Couldn't allocate memory "
                         "for sp - retried.\n");
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(host->host_lock);

                 LEAVE("qla2x00_queuecommand");
                 return(1);
@@ -2309,14 +2288,14 @@
                                 (int)ha->host_no,t,l);)

                 CMD_RESULT(cmd) = DID_NO_CONNECT << 16;
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(host->host_lock);
                 __sp_put(ha, sp);
                 return(0);
         }

         if (l >= ha->max_luns) {
                 CMD_RESULT(cmd) = DID_NO_CONNECT << 16;
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(host->host_lock);
                 __sp_put(ha, sp);
                 LEAVE("qla2x00_queuecommand");
                 return(0);
@@ -2379,7 +2358,7 @@
                 tasklet_schedule(&ha->run_qla_task);

                 LEAVE("qla2x00_queuecommand");
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(host->host_lock);
                 return (0);
         }

@@ -2427,7 +2406,7 @@
                 qla2x00_extend_timeout(sp->cmd ,60);

                 LEAVE("qla2x00_queuecommand");
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(host->host_lock);
                 return (0);
         } else {
                 sp->flags &= ~SRB_BUSY; /* v5.21b16 */
@@ -2449,7 +2428,7 @@
                 add_to_scsi_retry_queue(ha,sp);

                 LEAVE("qla2x00_queuecommand");
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(host->host_lock);
                 return (0);
         }

@@ -2462,7 +2441,7 @@

         COMTRACE('c')
         LEAVE("qla2x00_queuecommand");
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(host->host_lock);
         return (0);
  }

@@ -2526,10 +2505,10 @@
                         break;

- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(ha->host->host_lock);
                 set_current_state(TASK_INTERRUPTIBLE);
                 schedule_timeout(2*HZ);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(ha->host->host_lock);

         } while (time_before_eq(jiffies, max_wait_time));

@@ -2811,7 +2790,7 @@
                         sp_get(ha,sp);

                         spin_unlock_irqrestore(&ha->hardware_lock, flags);
- spin_unlock(&io_request_lock);
+ spin_unlock(host->host_lock);

                         if (qla2x00_abort_command(ha, sp)) {
                                 DEBUG2(printk("qla2xxx_eh_abort:
abort_command "
@@ -2825,7 +2804,7 @@
                         }

                         sp_put(ha,sp);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(host->host_lock);
                         spin_lock_irqsave(&ha->hardware_lock, flags);

                         /*
@@ -2862,15 +2841,15 @@
          */
         if ((which_ha & BIT_0) && (!list_empty(&ha->done_queue))) {
                 DEBUG3(printk("qla2xxx_eh_abort: calling done for ha.\n");)
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(host->host_lock);
                 qla2x00_done(ha);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(host->host_lock);
         }
         if ((which_ha & BIT_1) && (!list_empty(&vis_ha->done_queue))) {
                 DEBUG3(printk("qla2xxx_eh_abort: calling done for
vis_ha.\n");)
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(host->host_lock);
                 qla2x00_done(vis_ha);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(host->host_lock);
         }

         DEBUG(printk("qla2xxx_eh_abort: Exiting. return_status=0x%x.\n",
@@ -2975,22 +2954,22 @@
                 ha->cfg_active || ha->loop_state != LOOP_READY)) {

                 clear_bit(DEVICE_RESET_NEEDED, &ha->dpc_flags);
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(ha->host->host_lock);
                 if (qla2x00_device_reset(ha, t) != 0) {
                         return_status = FAILED;
                 }
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(ha->host->host_lock);
         } else {
                 /*
                  * Wait a while for the loop to come back. Return SUCCESS
                  * for the kernel to try again.
                  */
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(ha->host->host_lock);

                 set_current_state(TASK_INTERRUPTIBLE);
                 schedule_timeout(5 * HZ);

- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(ha->host->host_lock);

                 return_status = SUCCESS;
         }
@@ -3010,9 +2989,9 @@
                 DEBUG3(printk("qla2xxx_eh_device_reset: calling "
                                 "done for ha.\n");)

- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(ha->host->host_lock);
                 qla2x00_done(ha);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(ha->host->host_lock);
         }

         DRIVER_UNLOCK
@@ -3114,22 +3093,22 @@
                 ha->cfg_active || ha->loop_state != LOOP_READY)) {

                 clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags);
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(ha->host->host_lock);
                 if (qla2x00_loop_reset(ha) != 0) {
                         return_status = FAILED;
                 }
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(ha->host->host_lock);
         } else {
                 /*
                  * Wait a while for the loop to come back. Return SUCCESS
                  * for the kernel to try again.
                  */
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(ha->host->host_lock);

                 set_current_state(TASK_INTERRUPTIBLE);
                 schedule_timeout(5 * HZ);

- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(ha->host->host_lock);

                 return_status = SUCCESS;
         }
@@ -3147,9 +3126,9 @@
         if (!list_empty(&ha->done_queue)) {
                 DEBUG3(printk("qla2xxx_eh_bus_reset: calling done for
ha.\n");)

- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(ha->host->host_lock);
                 qla2x00_done(ha);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(ha->host->host_lock);
         }

         DEBUG2_3(printk("qla2xxx_eh_bus_reset: exiting. status=0x%x.\n",
@@ -3272,7 +3251,7 @@

         if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) {
                 set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(ha->host->host_lock);

                 if (qla2x00_abort_isp(ha, 1)) {
                         /* failed. try later */
@@ -3292,27 +3271,27 @@
                         return_status = SUCCESS;
                 }

- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(ha->host->host_lock);
                 clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
         } else {
                 /*
                  * Already active. Sleep a while then return SUCCESS for
                  * kernel to retry the IO.
                  */
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(ha->host->host_lock);

                 set_current_state(TASK_INTERRUPTIBLE);
                 schedule_timeout(5 * HZ);

- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(ha->host->host_lock);

                 return_status = SUCCESS;
         }

         if (!list_empty(&ha->done_queue)) {
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(ha->host->host_lock);
                 qla2x00_done(ha);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(ha->host->host_lock);
         }

         DRIVER_UNLOCK
@@ -3595,9 +3574,9 @@
                 tasklet_schedule(&ha->run_qla_task);

         if (found) {
- spin_unlock(&io_request_lock);
+ spin_unlock(ha->host->host_lock);
                 qla2x00_restart_queues(vis_ha, TRUE);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(ha->host->host_lock);
         } else {
                 printk(KERN_INFO
                         "qla2x00_abort: Couldn't Abort command = %p\n", cmd);
@@ -3851,12 +3830,12 @@
                          * mid-level code can expect completions
momentitarily.
                          */
  #if NEW_EH_CODE
- spin_unlock(&io_request_lock);
+ spin_unlock(ha->host->host_lock);
                         if (qla2x00_abort_isp(ha, 0)) {
                                 /* failed. try later */
                                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
                         }
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(ha->host->host_lock);
  #else
                         set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);

@@ -3874,9 +3853,9 @@
         DEBUG3(printk("qla2x00_reset: going to call restart_queues. "
                         "jiffies=%lx.\n", jiffies);)

- spin_unlock(&io_request_lock);
+ spin_unlock(ha->host->host_lock);
         qla2x00_restart_queues(ha,TRUE);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(ha->host->host_lock);
         DRIVER_UNLOCK

         COMTRACE('r')
@@ -3946,7 +3925,7 @@
         qla2x00_stats.irqhba = ha;

         /* Prevent concurrent access to adapters register */
- /* spin_lock_irqsave(&io_request_lock, cpu_flags);*/
+ /* spin_lock_irqsave(host->host_lock, cpu_flags);*/

         reg = ha->iobase;

@@ -3998,7 +3977,7 @@
         if (!list_empty(&ha->done_queue))
                 tasklet_schedule(&ha->run_qla_task);

- /* spin_unlock_irqrestore(&io_request_lock, cpu_flags);*/
+ /* spin_unlock_irqrestore(host->host_lock, cpu_flags);*/

         /* Wakeup the DPC routine */
         if ((!ha->flags.mbox_busy &&
@@ -4179,7 +4158,7 @@

                 QLA2100_DPC_LOCK(ha);

- /* spin_lock_irqsave(&io_request_lock, ha->cpu_flags);*/
+ /* spin_lock_irqsave(host->host_lock, ha->cpu_flags);*/
                 ha->dpc_active = 1;

                 /* Determine what action is necessary */
@@ -4477,7 +4456,7 @@
                 if (!list_empty(&ha->done_queue))
                         tasklet_schedule(&ha->run_qla_task);

- /* spin_unlock_irqrestore(&io_request_lock, ha->cpu_flags);*/
+ /* spin_unlock_irqrestore(host->host_lock, ha->cpu_flags);*/

                 ha->dpc_active = 0;

@@ -4778,9 +4757,9 @@

                 /* Call the mid-level driver interrupt handler */
  #if 0
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(host->host_lock, flags);
                 qla2x00_callback(ha,cmd);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
  #else

                 sp_put(ha, sp);
@@ -15846,7 +15825,7 @@
         printk(KERN_INFO
                 "qla2x00_apidev: open MAJOR number = %d, "
                 "MINOR number = %d\n",
- MAJOR(inode->i_rdev), MINOR(inode->i_rdev));
+ major(inode->i_rdev), minor(inode->i_rdev));

         return 0;
  }
@@ -15902,7 +15881,8 @@
                         APIDEV_NODE, apidev_major);)

         proc_mknod(APIDEV_NODE, 0777+S_IFCHR, host->hostt->proc_dir,
- (kdev_t)MKDEV(apidev_major,0));
+ (kdev_t)mk_kdev(apidev_major,0));
+

         return 0;
  }
diff -urN base/qla2x00.h 2.5.25/qla2x00.h
--- base/qla2x00.h Tue Apr 16 05:15:40 2002
+++ 2.5.25/qla2x00.h Fri Jul 12 09:29:51 2002
@@ -2682,10 +2682,8 @@
         present: 0, /* number of 7xxx's present */\
         unchecked_isa_dma: 0, /* no memory DMA restrictions */\
         use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 1, \
         max_sectors: 512, \
- highmem_io: 1, \
- emulated: 0 \
+ highmem_io: 1 \
  }
  #else /* KERNEL_VERSION < 2.5.7 */
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,8)
diff -urN base/qla2x00_ioctl.c 2.5.25/qla2x00_ioctl.c
--- base/qla2x00_ioctl.c Tue Apr 16 05:15:40 2002
+++ 2.5.25/qla2x00_ioctl.c Fri Jul 12 09:29:51 2002
@@ -2509,14 +2509,14 @@
                                 ha->host_no);)

                 /* get spin lock for this operation */
- spin_lock_irqsave(&io_request_lock, ha->cpu_flags);
+ spin_lock_irqsave(ha->host->host_lock, ha->cpu_flags);

         qla2x00_queuecommand(pscsi_cmd, (void *) qla2x00_scsi_pt_done);

         ha->ioctl->cmpl_timer.expires = jiffies + ha->ioctl->ioctl_tov * HZ;
         add_timer(&ha->ioctl->cmpl_timer);

- spin_unlock_irqrestore(&io_request_lock, ha->cpu_flags);
+ spin_unlock_irqrestore(ha->host->host_lock, ha->cpu_flags);
         down(&ha->ioctl->cmpl_sem);

         del_timer(&ha->ioctl->cmpl_timer);
===

cheers,

lincoln.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Jul 15 2002 - 22:00:21 EST