From: Vasu Dev <vasu.dev@intel.com>
To: linux-scsi@vger.kernel.org
Subject: [PATCH 4/5] fcoe: removed kzalloc from fcoe_ctlr_parse_adv (v3)
Date: Wed, 04 Mar 2009 10:53:58 -0800 [thread overview]
Message-ID: <20090304185358.22010.75646.stgit@vi2.jf.intel.com> (raw)
In-Reply-To: <20090304185025.22010.45242.stgit@vi2.jf.intel.com>
This patch eliminates fcoe_fcf memory allocation in fcoe_ctlr_parse_adv
for each incoming advertisement by having fcoe_ctlr_parse_adv caller provide
the fcoe_fcf pointer for parsing. The only current caller fcoe_ctlr_recv_adv
allocates fcoe_fcf memory only when a new FCF needs to be added to the FCFs
list.
Modified fcoe_ctlr_parse_adv ret value to int and fcoe_ctlr_recv_adv call
flow accordingly around fcoe_ctlr_parse_adv calling.
Signed-off-by: Vasu Dev <vasu.dev@intel.com>
---
drivers/scsi/libfcoe/fcoe_ctlr.c | 67 +++++++++++++++++++-------------------
1 files changed, 33 insertions(+), 34 deletions(-)
diff --git a/drivers/scsi/libfcoe/fcoe_ctlr.c b/drivers/scsi/libfcoe/fcoe_ctlr.c
index 42a67e0..d5a411b 100644
--- a/drivers/scsi/libfcoe/fcoe_ctlr.c
+++ b/drivers/scsi/libfcoe/fcoe_ctlr.c
@@ -558,11 +558,13 @@ static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
/*
* Decode a FIP advertisement into a new FCF entry.
+ *
+ * Returns zero on a valid parsed advertisement,
+ * otherwise returns non zero value.
*/
-static struct fcoe_fcf *fcoe_ctlr_parse_adv(struct sk_buff *skb)
+static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf)
{
struct fip_header *fiph;
- struct fcoe_fcf *fcf;
struct fip_desc *desc = NULL;
struct fip_wwn_desc *wwn;
struct fip_fab_desc *fab;
@@ -571,9 +573,7 @@ static struct fcoe_fcf *fcoe_ctlr_parse_adv(struct sk_buff *skb)
size_t rlen;
size_t dlen;
- fcf = kzalloc(sizeof(*fcf), GFP_ATOMIC);
- if (!fcf)
- return fcf;
+ memset(fcf, 0, sizeof(*fcf));
fcf->fka_period = msecs_to_jiffies(FCOE_CTLR_DEF_FKA);
fiph = (struct fip_header *)skb->data;
@@ -581,13 +581,13 @@ static struct fcoe_fcf *fcoe_ctlr_parse_adv(struct sk_buff *skb)
rlen = ntohs(fiph->fip_dl_len) * 4;
if (rlen + sizeof(*fiph) > skb->len)
- goto bad_adv;
+ return -EINVAL;
desc = (struct fip_desc *)(fiph + 1);
while (rlen > 0) {
dlen = desc->fip_dlen * FIP_BPW;
if (dlen < sizeof(*desc) || dlen > rlen)
- goto bad_adv;
+ return -EINVAL;
switch (desc->fip_dtype) {
case FIP_DT_PRI:
if (dlen != sizeof(struct fip_pri_desc))
@@ -602,7 +602,7 @@ static struct fcoe_fcf *fcoe_ctlr_parse_adv(struct sk_buff *skb)
ETH_ALEN);
if (!is_valid_ether_addr(fcf->fcf_mac)) {
FIP_DBG("invalid MAC addr in FIP adv\n");
- goto bad_adv;
+ return -EINVAL;
}
break;
case FIP_DT_NAME:
@@ -638,24 +638,22 @@ static struct fcoe_fcf *fcoe_ctlr_parse_adv(struct sk_buff *skb)
desc->fip_dtype);
/* standard says ignore unknown descriptors >= 128 */
if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
- goto bad_adv;
+ return -EINVAL;
continue;
}
desc = (struct fip_desc *)((char *)desc + dlen);
rlen -= dlen;
}
if (!fcf->fc_map || (fcf->fc_map & 0x10000))
- goto bad_adv;
+ return -EINVAL;
if (!fcf->switch_name || !fcf->fabric_name)
- goto bad_adv;
- return fcf;
+ return -EINVAL;
+ return 0;
len_err:
FIP_DBG("FIP length error in descriptor type %x len %zu\n",
desc->fip_dtype, dlen);
-bad_adv:
- kfree(fcf);
- return NULL;
+ return -EINVAL;
}
/*
@@ -664,54 +662,54 @@ bad_adv:
static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
struct fcoe_fcf *fcf;
- struct fcoe_fcf *new;
+ struct fcoe_fcf new;
struct fcoe_fcf *found;
unsigned long sol_tov = msecs_to_jiffies(FCOE_CTRL_SOL_TOV);
int first = 0;
int mtu_valid;
- new = fcoe_ctlr_parse_adv(skb);
- if (!new)
+ if (fcoe_ctlr_parse_adv(skb, &new))
return;
spin_lock_bh(&fip->lock);
first = list_empty(&fip->fcfs);
found = NULL;
list_for_each_entry(fcf, &fip->fcfs, list) {
- if (fcf->switch_name == new->switch_name &&
- fcf->fabric_name == new->fabric_name &&
- fcf->fc_map == new->fc_map &&
- compare_ether_addr(fcf->fcf_mac, new->fcf_mac) == 0) {
+ if (fcf->switch_name == new.switch_name &&
+ fcf->fabric_name == new.fabric_name &&
+ fcf->fc_map == new.fc_map &&
+ compare_ether_addr(fcf->fcf_mac, new.fcf_mac) == 0) {
found = fcf;
break;
}
}
if (!found) {
- if (fip->fcf_count >= FCOE_CTLR_FCF_LIMIT) {
- spin_unlock_bh(&fip->lock);
- kfree(new);
- return;
- }
+ if (fip->fcf_count >= FCOE_CTLR_FCF_LIMIT)
+ goto out;
+
+ fcf = kmalloc(sizeof(*fcf), GFP_ATOMIC);
+ if (!fcf)
+ goto out;
+
fip->fcf_count++;
- fcf = new;
+ memcpy(fcf, &new, sizeof(new));
list_add(&fcf->list, &fip->fcfs);
} else {
/*
* Once we've received a solicited advertisement, we should
* ignore the flags from multicast advertisments.
*/
- if ((new->flags & FIP_FL_SOL) || !(fcf->flags & FIP_FL_SOL))
- fcf->flags = new->flags;
+ if ((new.flags & FIP_FL_SOL) || !(fcf->flags & FIP_FL_SOL))
+ fcf->flags = new.flags;
if (fcf == fip->sel_fcf) {
fip->ctlr_ka_time -= fcf->fka_period;
- fip->ctlr_ka_time += new->fka_period;
+ fip->ctlr_ka_time += new.fka_period;
if (time_before(fip->ctlr_ka_time, fip->timer.expires))
mod_timer(&fip->timer, fip->ctlr_ka_time);
}
- fcf->fka_period = new->fka_period;
- memcpy(fcf->fcf_mac, new->fcf_mac, ETH_ALEN);
- kfree(new);
+ fcf->fka_period = new.fka_period;
+ memcpy(fcf->fcf_mac, new.fcf_mac, ETH_ALEN);
}
mtu_valid = fcoe_ctlr_mtu_valid(fcf);
fcf->time = jiffies;
@@ -746,6 +744,7 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
time_before(fip->sel_time, fip->timer.expires))
mod_timer(&fip->timer, fip->sel_time);
}
+out:
spin_unlock_bh(&fip->lock);
}
next prev parent reply other threads:[~2009-03-04 18:54 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-04 18:53 [PATCH 0/5] FIP feature for 2.6.30 merge window Vasu Dev
2009-03-04 18:53 ` [PATCH 1/5] fcoe: Add a header file defining the FIP protocol for FCoE Vasu Dev
2009-03-04 18:53 ` [PATCH 2/5] fcoe: Add support for the FIP discovery and keep-alive protocol Vasu Dev
2009-03-04 18:53 ` [PATCH 3/5] fcoe: libfcoe: fix FIP link logic Vasu Dev
2009-03-04 18:53 ` Vasu Dev [this message]
2009-03-04 18:54 ` [PATCH 5/5] fcoe: removes sharing of fcoe_rx_list for both FCoE and FIP frames Vasu Dev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090304185358.22010.75646.stgit@vi2.jf.intel.com \
--to=vasu.dev@intel.com \
--cc=linux-scsi@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.