diff options
Diffstat (limited to 'drivers/scsi/fcoe/fcoe.c')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 51 |
1 files changed, 25 insertions, 26 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index fd0b2b3b27b..927b3e63d87 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -1075,7 +1075,7 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu) struct sk_buff *skb; #ifdef CONFIG_SMP struct fcoe_percpu_s *p0; - unsigned targ_cpu = smp_processor_id(); + unsigned targ_cpu = get_cpu(); #endif /* CONFIG_SMP */ FCOE_DBG("Destroying receive thread for CPU %d\n", cpu); @@ -1131,6 +1131,7 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu) kfree_skb(skb); spin_unlock_bh(&p->fcoe_rx_list.lock); } + put_cpu(); #else /* * This a non-SMP scenario where the singular Rx thread is @@ -1299,8 +1300,8 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, return 0; err: - fc_lport_get_stats(lport)->ErrorFrames++; - + per_cpu_ptr(lport->dev_stats, get_cpu())->ErrorFrames++; + put_cpu(); err2: kfree_skb(skb); return -1; @@ -1529,9 +1530,10 @@ int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) skb_shinfo(skb)->gso_size = 0; } /* update tx stats: regardless if LLD fails */ - stats = fc_lport_get_stats(lport); + stats = per_cpu_ptr(lport->dev_stats, get_cpu()); stats->TxFrames++; stats->TxWords += wlen; + put_cpu(); /* send down to lld */ fr_dev(fp) = lport; @@ -1595,7 +1597,7 @@ static void fcoe_recv_frame(struct sk_buff *skb) hp = (struct fcoe_hdr *) skb_network_header(skb); fh = (struct fc_frame_header *) skb_transport_header(skb); - stats = fc_lport_get_stats(lport); + stats = per_cpu_ptr(lport->dev_stats, get_cpu()); if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) { if (stats->ErrorFrames < 5) printk(KERN_WARNING "fcoe: FCoE version " @@ -1604,9 +1606,7 @@ static void fcoe_recv_frame(struct sk_buff *skb) "initiator supports version " "%x\n", FC_FCOE_DECAPS_VER(hp), FC_FCOE_VER); - stats->ErrorFrames++; - kfree_skb(skb); - return; + goto drop; } skb_pull(skb, sizeof(struct fcoe_hdr)); @@ -1621,16 +1621,12 @@ static void fcoe_recv_frame(struct sk_buff *skb) fr_sof(fp) = hp->fcoe_sof; /* Copy out the CRC and EOF trailer for access */ - if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) { - kfree_skb(skb); - return; - } + if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) + goto drop; fr_eof(fp) = crc_eof.fcoe_eof; fr_crc(fp) = crc_eof.fcoe_crc32; - if (pskb_trim(skb, fr_len)) { - kfree_skb(skb); - return; - } + if (pskb_trim(skb, fr_len)) + goto drop; /* * We only check CRC if no offload is available and if it is @@ -1644,25 +1640,27 @@ static void fcoe_recv_frame(struct sk_buff *skb) fr_flags(fp) |= FCPHF_CRC_UNCHECKED; fh = fc_frame_header_get(fp); - if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA && - fh->fh_type == FC_TYPE_FCP) { - fc_exch_recv(lport, fp); - return; - } - if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) { + if ((fh->fh_r_ctl != FC_RCTL_DD_SOL_DATA || + fh->fh_type != FC_TYPE_FCP) && + (fr_flags(fp) & FCPHF_CRC_UNCHECKED)) { if (le32_to_cpu(fr_crc(fp)) != ~crc32(~0, skb->data, fr_len)) { if (stats->InvalidCRCCount < 5) printk(KERN_WARNING "fcoe: dropping " "frame with CRC error\n"); stats->InvalidCRCCount++; - stats->ErrorFrames++; - fc_frame_free(fp); - return; + goto drop; } fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; } + put_cpu(); fc_exch_recv(lport, fp); + return; + +drop: + stats->ErrorFrames++; + put_cpu(); + kfree_skb(skb); } /** @@ -1835,8 +1833,9 @@ static int fcoe_device_notification(struct notifier_block *notifier, if (link_possible && !fcoe_link_ok(lport)) fcoe_ctlr_link_up(&fcoe->ctlr); else if (fcoe_ctlr_link_down(&fcoe->ctlr)) { - stats = fc_lport_get_stats(lport); + stats = per_cpu_ptr(lport->dev_stats, get_cpu()); stats->LinkFailureCount++; + put_cpu(); fcoe_clean_pending_queue(lport); } out: |