Commit 386309ce authored by Joe Eykholt's avatar Joe Eykholt Committed by James Bottomley

[SCSI] libfcoe: fcoe: simplify receive FLOGI response

There was a locking problem where the fip->lock was held during
the call to update_mac().  The rtnl_lock() must be taken before
the fip->lock, not the other way around.  This fixes that.

Now that fcoe_ctlr_recv_flog() is called only from the response handler
to a FLOGI request, some checking can be eliminated.  Instead of calling
update_mac(), just fill in the granted_mac address for the passed-in
frame (skb).

Eliminate the passed-in source MAC address since it is also in the skb.

Also, in fcoe, call fcoe_set_src_mac() directly instead of going thru
the fip function pointer.  This will generate less code.
Then, since fip isn't needed for LOGO response, use lport as the arg.
Signed-off-by: default avatarJoe Eykholt <jeykholt@cisco.com>
Signed-off-by: default avatarRobert Love <robert.w.love@intel.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent e6d8a1b0
...@@ -2247,15 +2247,12 @@ static void fcoe_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg) ...@@ -2247,15 +2247,12 @@ static void fcoe_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
mac = fr_cb(fp)->granted_mac; mac = fr_cb(fp)->granted_mac;
if (is_zero_ether_addr(mac)) { if (is_zero_ether_addr(mac)) {
/* pre-FIP */ /* pre-FIP */
mac = eth_hdr(&fp->skb)->h_source; if (fcoe_ctlr_recv_flogi(fip, lport, fp)) {
if (fcoe_ctlr_recv_flogi(fip, lport, fp, mac)) {
fc_frame_free(fp); fc_frame_free(fp);
return; return;
} }
} else {
/* FIP, libfcoe has already seen it */
fip->update_mac(lport, fr_cb(fp)->granted_mac);
} }
fcoe_update_src_mac(lport, mac);
done: done:
fc_lport_flogi_resp(seq, fp, lport); fc_lport_flogi_resp(seq, fp, lport);
} }
...@@ -2271,13 +2268,11 @@ static void fcoe_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg) ...@@ -2271,13 +2268,11 @@ static void fcoe_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
*/ */
static void fcoe_logo_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg) static void fcoe_logo_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
{ {
struct fcoe_ctlr *fip = arg; struct fc_lport *lport = arg;
struct fc_exch *exch = fc_seq_exch(seq);
struct fc_lport *lport = exch->lp;
static u8 zero_mac[ETH_ALEN] = { 0 }; static u8 zero_mac[ETH_ALEN] = { 0 };
if (!IS_ERR(fp)) if (!IS_ERR(fp))
fip->update_mac(lport, zero_mac); fcoe_update_src_mac(lport, zero_mac);
fc_lport_logo_resp(seq, fp, lport); fc_lport_logo_resp(seq, fp, lport);
} }
...@@ -2312,7 +2307,7 @@ static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport, u32 did, ...@@ -2312,7 +2307,7 @@ static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport, u32 did,
if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI) if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI)
break; break;
return fc_elsct_send(lport, did, fp, op, fcoe_logo_resp, return fc_elsct_send(lport, did, fp, op, fcoe_logo_resp,
fip, timeout); lport, timeout);
} }
return fc_elsct_send(lport, did, fp, op, resp, arg, timeout); return fc_elsct_send(lport, did, fp, op, resp, arg, timeout);
} }
......
...@@ -1254,10 +1254,9 @@ static void fcoe_ctlr_recv_work(struct work_struct *recv_work) ...@@ -1254,10 +1254,9 @@ static void fcoe_ctlr_recv_work(struct work_struct *recv_work)
} }
/** /**
* fcoe_ctlr_recv_flogi() - Snoop pre-FIP receipt of FLOGI response or request * fcoe_ctlr_recv_flogi() - Snoop pre-FIP receipt of FLOGI response
* @fip: The FCoE controller * @fip: The FCoE controller
* @fp: The FC frame to snoop * @fp: The FC frame to snoop
* @sa: Ethernet source MAC address from received FCoE frame
* *
* Snoop potential response to FLOGI or even incoming FLOGI. * Snoop potential response to FLOGI or even incoming FLOGI.
* *
...@@ -1265,16 +1264,18 @@ static void fcoe_ctlr_recv_work(struct work_struct *recv_work) ...@@ -1265,16 +1264,18 @@ static void fcoe_ctlr_recv_work(struct work_struct *recv_work)
* by fip->flogi_oxid != FC_XID_UNKNOWN. * by fip->flogi_oxid != FC_XID_UNKNOWN.
* *
* The caller is responsible for freeing the frame. * The caller is responsible for freeing the frame.
* Fill in the granted_mac address.
* *
* Return non-zero if the frame should not be delivered to libfc. * Return non-zero if the frame should not be delivered to libfc.
*/ */
int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport, int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport,
struct fc_frame *fp, u8 *sa) struct fc_frame *fp)
{ {
struct fc_frame_header *fh; struct fc_frame_header *fh;
u8 op; u8 op;
u8 mac[ETH_ALEN]; u8 *sa;
sa = eth_hdr(&fp->skb)->h_source;
fh = fc_frame_header_get(fp); fh = fc_frame_header_get(fp);
if (fh->fh_type != FC_TYPE_ELS) if (fh->fh_type != FC_TYPE_ELS)
return 0; return 0;
...@@ -1305,9 +1306,8 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport, ...@@ -1305,9 +1306,8 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport,
fip->map_dest = 0; fip->map_dest = 0;
} }
fip->flogi_oxid = FC_XID_UNKNOWN; fip->flogi_oxid = FC_XID_UNKNOWN;
fc_fcoe_set_mac(mac, fh->fh_d_id);
fip->update_mac(lport, mac);
spin_unlock_bh(&fip->lock); spin_unlock_bh(&fip->lock);
fc_fcoe_set_mac(fr_cb(fp)->granted_mac, fh->fh_d_id);
} else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) { } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) {
/* /*
* Save source MAC for point-to-point responses. * Save source MAC for point-to-point responses.
......
...@@ -165,7 +165,7 @@ int fcoe_ctlr_link_down(struct fcoe_ctlr *); ...@@ -165,7 +165,7 @@ int fcoe_ctlr_link_down(struct fcoe_ctlr *);
int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct fc_lport *, struct sk_buff *); int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct fc_lport *, struct sk_buff *);
void fcoe_ctlr_recv(struct fcoe_ctlr *, struct sk_buff *); void fcoe_ctlr_recv(struct fcoe_ctlr *, struct sk_buff *);
int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *, int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *,
struct fc_frame *, u8 *); struct fc_frame *);
/* libfcoe funcs */ /* libfcoe funcs */
u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int); u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment