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 fd0b2b3b27b8..927b3e63d871 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) | |||
1075 | struct sk_buff *skb; | 1075 | struct sk_buff *skb; |
1076 | #ifdef CONFIG_SMP | 1076 | #ifdef CONFIG_SMP |
1077 | struct fcoe_percpu_s *p0; | 1077 | struct fcoe_percpu_s *p0; |
1078 | unsigned targ_cpu = smp_processor_id(); | 1078 | unsigned targ_cpu = get_cpu(); |
1079 | #endif /* CONFIG_SMP */ | 1079 | #endif /* CONFIG_SMP */ |
1080 | 1080 | ||
1081 | FCOE_DBG("Destroying receive thread for CPU %d\n", cpu); | 1081 | FCOE_DBG("Destroying receive thread for CPU %d\n", cpu); |
@@ -1131,6 +1131,7 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu) | |||
1131 | kfree_skb(skb); | 1131 | kfree_skb(skb); |
1132 | spin_unlock_bh(&p->fcoe_rx_list.lock); | 1132 | spin_unlock_bh(&p->fcoe_rx_list.lock); |
1133 | } | 1133 | } |
1134 | put_cpu(); | ||
1134 | #else | 1135 | #else |
1135 | /* | 1136 | /* |
1136 | * This a non-SMP scenario where the singular Rx thread is | 1137 | * 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, | |||
1299 | 1300 | ||
1300 | return 0; | 1301 | return 0; |
1301 | err: | 1302 | err: |
1302 | fc_lport_get_stats(lport)->ErrorFrames++; | 1303 | per_cpu_ptr(lport->dev_stats, get_cpu())->ErrorFrames++; |
1303 | 1304 | put_cpu(); | |
1304 | err2: | 1305 | err2: |
1305 | kfree_skb(skb); | 1306 | kfree_skb(skb); |
1306 | return -1; | 1307 | return -1; |
@@ -1529,9 +1530,10 @@ int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) | |||
1529 | skb_shinfo(skb)->gso_size = 0; | 1530 | skb_shinfo(skb)->gso_size = 0; |
1530 | } | 1531 | } |
1531 | /* update tx stats: regardless if LLD fails */ | 1532 | /* update tx stats: regardless if LLD fails */ |
1532 | stats = fc_lport_get_stats(lport); | 1533 | stats = per_cpu_ptr(lport->dev_stats, get_cpu()); |
1533 | stats->TxFrames++; | 1534 | stats->TxFrames++; |
1534 | stats->TxWords += wlen; | 1535 | stats->TxWords += wlen; |
1536 | put_cpu(); | ||
1535 | 1537 | ||
1536 | /* send down to lld */ | 1538 | /* send down to lld */ |
1537 | fr_dev(fp) = lport; | 1539 | fr_dev(fp) = lport; |
@@ -1595,7 +1597,7 @@ static void fcoe_recv_frame(struct sk_buff *skb) | |||
1595 | hp = (struct fcoe_hdr *) skb_network_header(skb); | 1597 | hp = (struct fcoe_hdr *) skb_network_header(skb); |
1596 | fh = (struct fc_frame_header *) skb_transport_header(skb); | 1598 | fh = (struct fc_frame_header *) skb_transport_header(skb); |
1597 | 1599 | ||
1598 | stats = fc_lport_get_stats(lport); | 1600 | stats = per_cpu_ptr(lport->dev_stats, get_cpu()); |
1599 | if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) { | 1601 | if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) { |
1600 | if (stats->ErrorFrames < 5) | 1602 | if (stats->ErrorFrames < 5) |
1601 | printk(KERN_WARNING "fcoe: FCoE version " | 1603 | printk(KERN_WARNING "fcoe: FCoE version " |
@@ -1604,9 +1606,7 @@ static void fcoe_recv_frame(struct sk_buff *skb) | |||
1604 | "initiator supports version " | 1606 | "initiator supports version " |
1605 | "%x\n", FC_FCOE_DECAPS_VER(hp), | 1607 | "%x\n", FC_FCOE_DECAPS_VER(hp), |
1606 | FC_FCOE_VER); | 1608 | FC_FCOE_VER); |
1607 | stats->ErrorFrames++; | 1609 | goto drop; |
1608 | kfree_skb(skb); | ||
1609 | return; | ||
1610 | } | 1610 | } |
1611 | 1611 | ||
1612 | skb_pull(skb, sizeof(struct fcoe_hdr)); | 1612 | skb_pull(skb, sizeof(struct fcoe_hdr)); |
@@ -1621,16 +1621,12 @@ static void fcoe_recv_frame(struct sk_buff *skb) | |||
1621 | fr_sof(fp) = hp->fcoe_sof; | 1621 | fr_sof(fp) = hp->fcoe_sof; |
1622 | 1622 | ||
1623 | /* Copy out the CRC and EOF trailer for access */ | 1623 | /* Copy out the CRC and EOF trailer for access */ |
1624 | if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) { | 1624 | if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) |
1625 | kfree_skb(skb); | 1625 | goto drop; |
1626 | return; | ||
1627 | } | ||
1628 | fr_eof(fp) = crc_eof.fcoe_eof; | 1626 | fr_eof(fp) = crc_eof.fcoe_eof; |
1629 | fr_crc(fp) = crc_eof.fcoe_crc32; | 1627 | fr_crc(fp) = crc_eof.fcoe_crc32; |
1630 | if (pskb_trim(skb, fr_len)) { | 1628 | if (pskb_trim(skb, fr_len)) |
1631 | kfree_skb(skb); | 1629 | goto drop; |
1632 | return; | ||
1633 | } | ||
1634 | 1630 | ||
1635 | /* | 1631 | /* |
1636 | * We only check CRC if no offload is available and if it is | 1632 | * 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) | |||
1644 | fr_flags(fp) |= FCPHF_CRC_UNCHECKED; | 1640 | fr_flags(fp) |= FCPHF_CRC_UNCHECKED; |
1645 | 1641 | ||
1646 | fh = fc_frame_header_get(fp); | 1642 | fh = fc_frame_header_get(fp); |
1647 | if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA && | 1643 | if ((fh->fh_r_ctl != FC_RCTL_DD_SOL_DATA || |
1648 | fh->fh_type == FC_TYPE_FCP) { | 1644 | fh->fh_type != FC_TYPE_FCP) && |
1649 | fc_exch_recv(lport, fp); | 1645 | (fr_flags(fp) & FCPHF_CRC_UNCHECKED)) { |
1650 | return; | ||
1651 | } | ||
1652 | if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) { | ||
1653 | if (le32_to_cpu(fr_crc(fp)) != | 1646 | if (le32_to_cpu(fr_crc(fp)) != |
1654 | ~crc32(~0, skb->data, fr_len)) { | 1647 | ~crc32(~0, skb->data, fr_len)) { |
1655 | if (stats->InvalidCRCCount < 5) | 1648 | if (stats->InvalidCRCCount < 5) |
1656 | printk(KERN_WARNING "fcoe: dropping " | 1649 | printk(KERN_WARNING "fcoe: dropping " |
1657 | "frame with CRC error\n"); | 1650 | "frame with CRC error\n"); |
1658 | stats->InvalidCRCCount++; | 1651 | stats->InvalidCRCCount++; |
1659 | stats->ErrorFrames++; | 1652 | goto drop; |
1660 | fc_frame_free(fp); | ||
1661 | return; | ||
1662 | } | 1653 | } |
1663 | fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; | 1654 | fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; |
1664 | } | 1655 | } |
1656 | put_cpu(); | ||
1665 | fc_exch_recv(lport, fp); | 1657 | fc_exch_recv(lport, fp); |
1658 | return; | ||
1659 | |||
1660 | drop: | ||
1661 | stats->ErrorFrames++; | ||
1662 | put_cpu(); | ||
1663 | kfree_skb(skb); | ||
1666 | } | 1664 | } |
1667 | 1665 | ||
1668 | /** | 1666 | /** |
@@ -1835,8 +1833,9 @@ static int fcoe_device_notification(struct notifier_block *notifier, | |||
1835 | if (link_possible && !fcoe_link_ok(lport)) | 1833 | if (link_possible && !fcoe_link_ok(lport)) |
1836 | fcoe_ctlr_link_up(&fcoe->ctlr); | 1834 | fcoe_ctlr_link_up(&fcoe->ctlr); |
1837 | else if (fcoe_ctlr_link_down(&fcoe->ctlr)) { | 1835 | else if (fcoe_ctlr_link_down(&fcoe->ctlr)) { |
1838 | stats = fc_lport_get_stats(lport); | 1836 | stats = per_cpu_ptr(lport->dev_stats, get_cpu()); |
1839 | stats->LinkFailureCount++; | 1837 | stats->LinkFailureCount++; |
1838 | put_cpu(); | ||
1840 | fcoe_clean_pending_queue(lport); | 1839 | fcoe_clean_pending_queue(lport); |
1841 | } | 1840 | } |
1842 | out: | 1841 | out: |