mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-04-02 12:23:49 +00:00
[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: Joe Eykholt <jeykholt@cisco.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
parent
e6d8a1b0b5
commit
386309ce92
3 changed files with 12 additions and 17 deletions
|
@ -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 @@ done:
|
||||||
*/
|
*/
|
||||||
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,
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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)
|
||||||
* 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,
|
||||||
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 *);
|
||||||
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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue