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

scsi: gdth: remove gdth_{alloc,free}_ioctl

Out of the three callers once insists on the scratch buffer, and the
others are fine with a new allocation. Switch those two to just use
pci_alloc_consistent directly, and open code the scratch buffer
allocation in the remaining one. This avoids a case where we might
be doing a memory allocation under a spinlock with irqs disabled.

[mkp: typo]

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Christoph Hellwig and committed by
Martin K. Petersen
463563fa 8d22022c

+25 -57
+4 -4
drivers/scsi/gdth.c
··· 4239 4239 gdth_ioctl_general gen; 4240 4240 gdth_ha_str *ha; 4241 4241 char *buf = NULL; 4242 - u64 paddr; 4242 + dma_addr_t paddr; 4243 4243 int rval; 4244 4244 4245 4245 if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general))) ··· 4256 4256 return -EINVAL; 4257 4257 4258 4258 if (gen.data_len + gen.sense_len > 0) { 4259 - buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len, FALSE, 4260 - &paddr); 4259 + buf = pci_alloc_consistent(ha->pdev, 4260 + gen.data_len + gen.sense_len, &paddr); 4261 4261 if (!buf) 4262 4262 return -EFAULT; 4263 4263 ··· 4292 4292 4293 4293 rval = 0; 4294 4294 out_free_buf: 4295 - gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); 4295 + pci_free_consistent(ha->pdev, gen.data_len + gen.sense_len, buf, paddr); 4296 4296 return rval; 4297 4297 } 4298 4298
+21 -50
drivers/scsi/gdth_proc.c
··· 31 31 int i, found; 32 32 gdth_cmd_str gdtcmd; 33 33 gdth_cpar_str *pcpar; 34 - u64 paddr; 35 34 36 35 char cmnd[MAX_COMMAND_SIZE]; 37 36 memset(cmnd, 0xff, 12); ··· 112 113 } 113 114 114 115 if (wb_mode) { 115 - if (!gdth_ioctl_alloc(ha, sizeof(gdth_cpar_str), TRUE, &paddr)) 116 - return(-EBUSY); 116 + unsigned long flags; 117 + 118 + BUILD_BUG_ON(sizeof(gdth_cpar_str) > GDTH_SCRATCH); 119 + 120 + spin_lock_irqsave(&ha->smp_lock, flags); 121 + if (ha->scratch_busy) { 122 + spin_unlock_irqrestore(&ha->smp_lock, flags); 123 + return -EBUSY; 124 + } 125 + ha->scratch_busy = TRUE; 126 + spin_unlock_irqrestore(&ha->smp_lock, flags); 127 + 117 128 pcpar = (gdth_cpar_str *)ha->pscratch; 118 129 memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) ); 119 130 gdtcmd.Service = CACHESERVICE; 120 131 gdtcmd.OpCode = GDT_IOCTL; 121 - gdtcmd.u.ioctl.p_param = paddr; 132 + gdtcmd.u.ioctl.p_param = ha->scratch_phys; 122 133 gdtcmd.u.ioctl.param_size = sizeof(gdth_cpar_str); 123 134 gdtcmd.u.ioctl.subfunc = CACHE_CONFIG; 124 135 gdtcmd.u.ioctl.channel = INVALID_CHANNEL; ··· 136 127 137 128 gdth_execute(host, &gdtcmd, cmnd, 30, NULL); 138 129 139 - gdth_ioctl_free(ha, GDTH_SCRATCH, ha->pscratch, paddr); 130 + spin_lock_irqsave(&ha->smp_lock, flags); 131 + ha->scratch_busy = FALSE; 132 + spin_unlock_irqrestore(&ha->smp_lock, flags); 133 + 140 134 printk("Done.\n"); 141 135 return(orig_length); 142 136 } ··· 155 143 int id, i, j, k, sec, flag; 156 144 int no_mdrv = 0, drv_no, is_mirr; 157 145 u32 cnt; 158 - u64 paddr; 146 + dma_addr_t paddr; 159 147 int rc = -ENOMEM; 160 148 161 149 gdth_cmd_str *gdtcmd; ··· 244 232 seq_puts(m, "\nPhysical Devices:"); 245 233 flag = FALSE; 246 234 247 - buf = gdth_ioctl_alloc(ha, size, FALSE, &paddr); 235 + buf = pci_alloc_consistent(ha->pdev, size, &paddr); 248 236 if (!buf) 249 237 goto stop_output; 250 238 for (i = 0; i < ha->bus_cnt; ++i) { ··· 418 406 seq_printf(m, 419 407 " To Array Drv.:\t%s\n", hrec); 420 408 } 421 - 409 + 422 410 if (!flag) 423 411 seq_puts(m, "\n --\n"); 424 412 ··· 512 500 } 513 501 } 514 502 } 515 - gdth_ioctl_free(ha, size, buf, paddr); 503 + pci_free_consistent(ha->pdev, size, buf, paddr); 516 504 517 505 for (i = 0; i < MAX_HDRIVES; ++i) { 518 506 if (!(ha->hdr[i].present)) ··· 563 551 kfree(gdtcmd); 564 552 kfree(estr); 565 553 return rc; 566 - } 567 - 568 - static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch, 569 - u64 *paddr) 570 - { 571 - unsigned long flags; 572 - char *ret_val; 573 - 574 - if (size == 0) 575 - return NULL; 576 - 577 - spin_lock_irqsave(&ha->smp_lock, flags); 578 - 579 - if (!ha->scratch_busy && size <= GDTH_SCRATCH) { 580 - ha->scratch_busy = TRUE; 581 - ret_val = ha->pscratch; 582 - *paddr = ha->scratch_phys; 583 - } else if (scratch) { 584 - ret_val = NULL; 585 - } else { 586 - dma_addr_t dma_addr; 587 - 588 - ret_val = pci_alloc_consistent(ha->pdev, size, &dma_addr); 589 - *paddr = dma_addr; 590 - } 591 - 592 - spin_unlock_irqrestore(&ha->smp_lock, flags); 593 - return ret_val; 594 - } 595 - 596 - static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, u64 paddr) 597 - { 598 - unsigned long flags; 599 - 600 - if (buf == ha->pscratch) { 601 - spin_lock_irqsave(&ha->smp_lock, flags); 602 - ha->scratch_busy = FALSE; 603 - spin_unlock_irqrestore(&ha->smp_lock, flags); 604 - } else { 605 - pci_free_consistent(ha->pdev, size, buf, paddr); 606 - } 607 554 } 608 555 609 556 #ifdef GDTH_IOCTL_PROC
-3
drivers/scsi/gdth_proc.h
··· 12 12 static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, 13 13 int length, gdth_ha_str *ha); 14 14 15 - static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch, 16 - u64 *paddr); 17 - static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, u64 paddr); 18 15 static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id); 19 16 20 17 #endif