Skip to content

Commit

Permalink
[SCSI] fcoe: Fix write errors on NPIV ports
Browse files Browse the repository at this point in the history
SCSI errors were generated while writing to LUNs
connected via NPIV ports.

Debugging this it was found that the FCoE packets
transmitted via the NPIV ports were not tagged with
correct user priority as negotiated with peer by DCB
agent. This resulted in FCoE traffic going with priority
zero(0) that did not have priority flow control (PFC)
enabled for it. The initiator after transferring data
to the target never saw any reply indicating the transfer
was complete. This resulted in error recovery (ABTS) and
SCSI command retries by the scsi-mid layer; eventually
resulting in I/O errors.

This patch fixes this issue by keeping the FCoE user
priority information in the fcoe_interface instance
that is common for both the physical port as well as
NPIV ports connected to that physical port; instead
of storing it in fcoe_port structure that has a per
port instance.

Signed-off-by: Neerav Parikh <[email protected]>
Acked-by: Yi Zou <[email protected]>
Acked-by: John Fastabend <[email protected]>
Tested-by: Marcus Dennis <[email protected]>
Signed-off-by: Robert Love <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
  • Loading branch information
Neerav Parikh authored and James Bottomley committed Oct 7, 2012
1 parent bd756dd commit 31c37a6
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 11 deletions.
14 changes: 5 additions & 9 deletions drivers/scsi/fcoe/fcoe.c
Original file line number Diff line number Diff line change
Expand Up @@ -1643,7 +1643,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
skb_reset_network_header(skb);
skb->mac_len = elen;
skb->protocol = htons(ETH_P_FCOE);
skb->priority = port->priority;
skb->priority = fcoe->priority;

if (fcoe->netdev->priv_flags & IFF_802_1Q_VLAN &&
fcoe->realdev->features & NETIF_F_HW_VLAN_TX) {
Expand Down Expand Up @@ -1917,7 +1917,6 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier,
struct fcoe_ctlr *ctlr;
struct fcoe_interface *fcoe;
struct net_device *netdev;
struct fcoe_port *port;
int prio;

if (entry->app.selector != DCB_APP_IDTYPE_ETHTYPE)
Expand Down Expand Up @@ -1946,10 +1945,8 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier,
entry->app.protocol == ETH_P_FCOE)
ctlr->priority = prio;

if (entry->app.protocol == ETH_P_FCOE) {
port = lport_priv(ctlr->lp);
port->priority = prio;
}
if (entry->app.protocol == ETH_P_FCOE)
fcoe->priority = prio;

return NOTIFY_OK;
}
Expand Down Expand Up @@ -2180,7 +2177,6 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe)
u8 fup, up;
struct net_device *netdev = fcoe->realdev;
struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
struct fcoe_port *port = lport_priv(ctlr->lp);
struct dcb_app app = {
.priority = 0,
.protocol = ETH_P_FCOE
Expand All @@ -2202,8 +2198,8 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe)
fup = dcb_getapp(netdev, &app);
}

port->priority = ffs(up) ? ffs(up) - 1 : 0;
ctlr->priority = ffs(fup) ? ffs(fup) - 1 : port->priority;
fcoe->priority = ffs(up) ? ffs(up) - 1 : 0;
ctlr->priority = ffs(fup) ? ffs(fup) - 1 : fcoe->priority;
}
#endif
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/scsi/fcoe/fcoe.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ do { \
* @oem: The offload exchange manager for all local port
* instances associated with this port
* @removed: Indicates fcoe interface removed from net device
* @priority: Priority for the FCoE packet (DCB)
* This structure is 1:1 with a net device.
*/
struct fcoe_interface {
Expand All @@ -81,6 +82,7 @@ struct fcoe_interface {
struct packet_type fip_packet_type;
struct fc_exch_mgr *oem;
u8 removed;
u8 priority;
};

#define fcoe_to_ctlr(x) \
Expand Down
2 changes: 0 additions & 2 deletions include/scsi/libfcoe.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,6 @@ struct fcoe_percpu_s {
* @lport: The associated local port
* @fcoe_pending_queue: The pending Rx queue of skbs
* @fcoe_pending_queue_active: Indicates if the pending queue is active
* @priority: Packet priority (DCB)
* @max_queue_depth: Max queue depth of pending queue
* @min_queue_depth: Min queue depth of pending queue
* @timer: The queue timer
Expand All @@ -343,7 +342,6 @@ struct fcoe_port {
struct fc_lport *lport;
struct sk_buff_head fcoe_pending_queue;
u8 fcoe_pending_queue_active;
u8 priority;
u32 max_queue_depth;
u32 min_queue_depth;
struct timer_list timer;
Expand Down

0 comments on commit 31c37a6

Please sign in to comment.