aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc
diff options
context:
space:
mode:
authorJoe Eykholt <jeykholt@cisco.com>2010-03-12 19:08:55 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-04-11 10:23:44 -0400
commitf018b73af6db4f330ad5da9ac53997a699c30c42 (patch)
tree4f4e9405d923c0021771549dbdec34569c0e27a7 /drivers/scsi/libfc
parentb3ef990c1514859bffae221b9e82e46a38f1e7bf (diff)
[SCSI] libfc, libfcoe, fcoe: use smp_processor_id() only when preempt disabled
When the kernel is configured for preemption, using smp_processor_id() when preemption is enabled causes a warning backtrace and is wrong since we could move off of that CPU as soon as we get the ID, and we would be referencing the wrong CPU, and possibly an invalid one if it could be hotswapped out. Remove the fc_lport_get_stats() function and explicitly use per_cpu_ptr() to get the statistics. Where preemption has been disabled by holding a _bh lock continue to use smp_processor_id(), but otherwise use get_cpu()/put_cpu(). In fcoe_recv_frame() also changed the cases where we return in the middle to do a goto to the code which bumps ErrorFrames and does a put_cpu(). Two of these cases didn't bump ErrorFrames before, but doing so is harmless because they "can't happen", due to prior length checks. Also rearranged code in fcoe_recv_frame() to have only one call to fc_exch_recv(). It's just as efficient and saves a call to put_cpu(). In fc_fcp.c, adjusted a FIXME comment for code which doesn't need fixing. Signed-off-by: Joe Eykholt <jeykholt@cisco.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r--drivers/scsi/libfc/fc_exch.c3
-rw-r--r--drivers/scsi/libfc/fc_fcp.c8
2 files changed, 7 insertions, 4 deletions
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index dc12a2bf0c9b..d0496dafd84a 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -676,9 +676,10 @@ static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
676 } 676 }
677 memset(ep, 0, sizeof(*ep)); 677 memset(ep, 0, sizeof(*ep));
678 678
679 cpu = smp_processor_id(); 679 cpu = get_cpu();
680 pool = per_cpu_ptr(mp->pool, cpu); 680 pool = per_cpu_ptr(mp->pool, cpu);
681 spin_lock_bh(&pool->lock); 681 spin_lock_bh(&pool->lock);
682 put_cpu();
682 index = pool->next_index; 683 index = pool->next_index;
683 /* allocate new exch from pool */ 684 /* allocate new exch from pool */
684 while (fc_exch_ptr_get(pool, index)) { 685 while (fc_exch_ptr_get(pool, index)) {
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 044c420a1371..220c4bc536ca 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -484,13 +484,14 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
484 484
485 if (~crc != le32_to_cpu(fr_crc(fp))) { 485 if (~crc != le32_to_cpu(fr_crc(fp))) {
486crc_err: 486crc_err:
487 stats = fc_lport_get_stats(lport); 487 stats = per_cpu_ptr(lport->dev_stats, get_cpu());
488 stats->ErrorFrames++; 488 stats->ErrorFrames++;
489 /* FIXME - per cpu count, not total count! */ 489 /* per cpu count, not total count, but OK for limit */
490 if (stats->InvalidCRCCount++ < 5) 490 if (stats->InvalidCRCCount++ < 5)
491 printk(KERN_WARNING "libfc: CRC error on data " 491 printk(KERN_WARNING "libfc: CRC error on data "
492 "frame for port (%6x)\n", 492 "frame for port (%6x)\n",
493 fc_host_port_id(lport->host)); 493 fc_host_port_id(lport->host));
494 put_cpu();
494 /* 495 /*
495 * Assume the frame is total garbage. 496 * Assume the frame is total garbage.
496 * We may have copied it over the good part 497 * We may have copied it over the good part
@@ -1819,7 +1820,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
1819 /* 1820 /*
1820 * setup the data direction 1821 * setup the data direction
1821 */ 1822 */
1822 stats = fc_lport_get_stats(lport); 1823 stats = per_cpu_ptr(lport->dev_stats, get_cpu());
1823 if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) { 1824 if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) {
1824 fsp->req_flags = FC_SRB_READ; 1825 fsp->req_flags = FC_SRB_READ;
1825 stats->InputRequests++; 1826 stats->InputRequests++;
@@ -1832,6 +1833,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
1832 fsp->req_flags = 0; 1833 fsp->req_flags = 0;
1833 stats->ControlRequests++; 1834 stats->ControlRequests++;
1834 } 1835 }
1836 put_cpu();
1835 1837
1836 fsp->tgt_flags = rpriv->flags; 1838 fsp->tgt_flags = rpriv->flags;
1837 1839