[SCSI] libfcoe: fcoe: simplify receive FLOGI response
Joe Eykholt [Tue, 3 Nov 2009 19:49:16 +0000 (11:49 -0800)]
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>

drivers/scsi/fcoe/fcoe.c
drivers/scsi/fcoe/libfcoe.c
include/scsi/libfcoe.h

index b15ec99..343900a 100644 (file)
@@ -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;
        if (is_zero_ether_addr(mac)) {
                /* pre-FIP */
-               mac = eth_hdr(&fp->skb)->h_source;
-               if (fcoe_ctlr_recv_flogi(fip, lport, fp, mac)) {
+               if (fcoe_ctlr_recv_flogi(fip, lport, fp)) {
                        fc_frame_free(fp);
                        return;
                }
-       } else {
-               /* FIP, libfcoe has already seen it */
-               fip->update_mac(lport, fr_cb(fp)->granted_mac);
        }
+       fcoe_update_src_mac(lport, mac);
 done:
        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)
 {
-       struct fcoe_ctlr *fip = arg;
-       struct fc_exch *exch = fc_seq_exch(seq);
-       struct fc_lport *lport = exch->lp;
+       struct fc_lport *lport = arg;
        static u8 zero_mac[ETH_ALEN] = { 0 };
 
        if (!IS_ERR(fp))
-               fip->update_mac(lport, zero_mac);
+               fcoe_update_src_mac(lport, zero_mac);
        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)
                        break;
                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);
 }
index 2aab972..2988b71 100644 (file)
@@ -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
  * @fp:         The FC frame to snoop
- * @sa:         Ethernet source MAC address from received FCoE frame
  *
  * 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.
  *
  * 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.
  */
 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;
        u8 op;
-       u8 mac[ETH_ALEN];
+       u8 *sa;
 
+       sa = eth_hdr(&fp->skb)->h_source;
        fh = fc_frame_header_get(fp);
        if (fh->fh_type != FC_TYPE_ELS)
                return 0;
@@ -1305,9 +1306,8 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport,
                        fip->map_dest = 0;
                }
                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);
+               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) {
                /*
                 * Save source MAC for point-to-point responses.
index e38ffa0..3837872 100644 (file)
@@ -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 *);
 void fcoe_ctlr_recv(struct fcoe_ctlr *, struct sk_buff *);
 int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *,
-                        struct fc_frame *, u8 *);
+                        struct fc_frame *);
 
 /* libfcoe funcs */
 u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int);