Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] mvsas: Add support for interrupt tasklet

Add support for interrupt tasklet, which will improve performance.
Correct spelling of "20011"

[jejb: simplified ifdefs and fixed unused variable problem]
Signed-off-by: Xiangliang Yu <yuxiangl@marvell.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>

authored by

Xiangliang Yu and committed by
James Bottomley
6f8ac161 e144f7ef

+40 -26
+8 -1
drivers/scsi/mvsas/Kconfig
··· 3 3 # 4 4 # Copyright 2007 Red Hat, Inc. 5 5 # Copyright 2008 Marvell. <kewei@marvell.com> 6 - # Copyright 2009-20011 Marvell. <yuxiangl@marvell.com> 6 + # Copyright 2009-2011 Marvell. <yuxiangl@marvell.com> 7 7 # 8 8 # This file is licensed under GPLv2. 9 9 # ··· 41 41 help 42 42 Compiles the 88SE64XX/88SE94XX driver in debug mode. In debug mode, 43 43 the driver prints some messages to the console. 44 + config SCSI_MVSAS_TASKLET 45 + bool "Support for interrupt tasklet" 46 + default n 47 + depends on SCSI_MVSAS 48 + help 49 + Compiles the 88SE64xx/88SE94xx driver in interrupt tasklet mode.In this mode, 50 + the interrupt will schedule a tasklet.
+2 -4
drivers/scsi/mvsas/mv_64xx.c
··· 471 471 472 472 /* clear CMD_CMPLT ASAP */ 473 473 mw32_f(MVS_INT_STAT, CINT_DONE); 474 - #ifndef MVS_USE_TASKLET 474 + 475 475 spin_lock(&mvi->lock); 476 - #endif 477 476 mvs_int_full(mvi); 478 - #ifndef MVS_USE_TASKLET 479 477 spin_unlock(&mvi->lock); 480 - #endif 478 + 481 479 return IRQ_HANDLED; 482 480 } 483 481
+1 -4
drivers/scsi/mvsas/mv_94xx.c
··· 579 579 if (((stat & IRQ_SAS_A) && mvi->id == 0) || 580 580 ((stat & IRQ_SAS_B) && mvi->id == 1)) { 581 581 mw32_f(MVS_INT_STAT, CINT_DONE); 582 - #ifndef MVS_USE_TASKLET 582 + 583 583 spin_lock(&mvi->lock); 584 - #endif 585 584 mvs_int_full(mvi); 586 - #ifndef MVS_USE_TASKLET 587 585 spin_unlock(&mvi->lock); 588 - #endif 589 586 } 590 587 return IRQ_HANDLED; 591 588 }
+28 -17
drivers/scsi/mvsas/mv_init.c
··· 170 170 kfree(mvi); 171 171 } 172 172 173 - #ifdef MVS_USE_TASKLET 174 - struct tasklet_struct mv_tasklet; 173 + #ifdef CONFIG_SCSI_MVSAS_TASKLET 175 174 static void mvs_tasklet(unsigned long opaque) 176 175 { 177 - unsigned long flags; 178 176 u32 stat; 179 177 u16 core_nr, i = 0; 180 178 ··· 185 187 if (unlikely(!mvi)) 186 188 BUG_ON(1); 187 189 190 + stat = MVS_CHIP_DISP->isr_status(mvi, mvi->pdev->irq); 191 + if (!stat) 192 + goto out; 193 + 188 194 for (i = 0; i < core_nr; i++) { 189 195 mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i]; 190 - stat = MVS_CHIP_DISP->isr_status(mvi, mvi->irq); 191 - if (stat) 192 - MVS_CHIP_DISP->isr(mvi, mvi->irq, stat); 196 + MVS_CHIP_DISP->isr(mvi, mvi->pdev->irq, stat); 193 197 } 198 + out: 199 + MVS_CHIP_DISP->interrupt_enable(mvi); 194 200 195 201 } 196 202 #endif 197 203 198 204 static irqreturn_t mvs_interrupt(int irq, void *opaque) 199 205 { 200 - u32 core_nr, i = 0; 206 + u32 core_nr; 201 207 u32 stat; 202 208 struct mvs_info *mvi; 203 209 struct sas_ha_struct *sha = opaque; 210 + #ifndef CONFIG_SCSI_MVSAS_TASKLET 211 + u32 i; 212 + #endif 204 213 205 214 core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host; 206 215 mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0]; 207 216 208 217 if (unlikely(!mvi)) 209 218 return IRQ_NONE; 219 + #ifdef CONFIG_SCSI_MVSAS_TASKLET 220 + MVS_CHIP_DISP->interrupt_disable(mvi); 221 + #endif 210 222 211 223 stat = MVS_CHIP_DISP->isr_status(mvi, irq); 212 - if (!stat) 224 + if (!stat) { 225 + #ifdef CONFIG_SCSI_MVSAS_TASKLET 226 + MVS_CHIP_DISP->interrupt_enable(mvi); 227 + #endif 213 228 return IRQ_NONE; 229 + } 214 230 215 - #ifdef MVS_USE_TASKLET 216 - tasklet_schedule(&mv_tasklet); 231 + #ifdef CONFIG_SCSI_MVSAS_TASKLET 232 + tasklet_schedule(&((struct mvs_prv_info *)sha->lldd_ha)->mv_tasklet); 217 233 #else 218 234 for (i = 0; i < core_nr; i++) { 219 235 mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i]; ··· 400 388 mvi->id = id; 401 389 mvi->sas = sha; 402 390 mvi->shost = shost; 403 - #ifdef MVS_USE_TASKLET 404 - tasklet_init(&mv_tasklet, mvs_tasklet, (unsigned long)sha); 405 - #endif 406 391 407 392 mvi->tags = kzalloc(MVS_CHIP_SLOT_SZ>>3, GFP_KERNEL); 408 393 if (!mvi->tags) ··· 544 535 { 545 536 unsigned int rc, nhost = 0; 546 537 struct mvs_info *mvi; 538 + struct mvs_prv_info *mpi; 547 539 irq_handler_t irq_handler = mvs_interrupt; 548 540 struct Scsi_Host *shost = NULL; 549 541 const struct mvs_chip_info *chip; ··· 609 599 } 610 600 nhost++; 611 601 } while (nhost < chip->n_host); 612 - #ifdef MVS_USE_TASKLET 613 - tasklet_init(&mv_tasklet, mvs_tasklet, 602 + mpi = (struct mvs_prv_info *)(SHOST_TO_SAS_HA(shost)->lldd_ha); 603 + #ifdef CONFIG_SCSI_MVSAS_TASKLET 604 + tasklet_init(&(mpi->mv_tasklet), mvs_tasklet, 614 605 (unsigned long)SHOST_TO_SAS_HA(shost)); 615 606 #endif 616 607 ··· 656 645 core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host; 657 646 mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0]; 658 647 659 - #ifdef MVS_USE_TASKLET 660 - tasklet_kill(&mv_tasklet); 648 + #ifdef CONFIG_SCSI_MVSAS_TASKLET 649 + tasklet_kill(&((struct mvs_prv_info *)sha->lldd_ha)->mv_tasklet); 661 650 #endif 662 651 663 652 pci_set_drvdata(pdev, NULL);
+1
drivers/scsi/mvsas/mv_sas.h
··· 420 420 u8 scan_finished; 421 421 u8 reserve; 422 422 struct mvs_info *mvi[2]; 423 + struct tasklet_struct mv_tasklet; 423 424 }; 424 425 425 426 struct mvs_wq {