From: "Bhanu Prakash Gollapudi" <bprakash@broadcom.com>
To: JBottomley@parallels.com, linux-scsi@vger.kernel.org
Cc: michaelc@cs.wisc.edu, mchan@broadcom.com,
robert.w.love@intel.com, devel@open-fcoe.org,
Bhanu Prakash Gollapudi <bprakash@broadcom.com>
Subject: [PATCH v2 08/18] bnx2fc: Handle NETDEV_UNREGISTER for vlan devices
Date: Thu, 4 Aug 2011 17:38:42 -0700 [thread overview]
Message-ID: <1312504732-4572-9-git-send-email-bprakash@broadcom.com> (raw)
In-Reply-To: <1312504732-4572-1-git-send-email-bprakash@broadcom.com>
Since the driver holds the reference for vlan netdev, the reference has to be
released by the driver when the vlan device is removed. Driver handles this in
NETDEV_UNREGISTER event.
Signed-off-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com>
---
drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 92 +++++++++++++++++++++++--------------
1 files changed, 57 insertions(+), 35 deletions(-)
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index 673c97c..dccabaf 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
@@ -56,6 +56,7 @@ static struct scsi_host_template bnx2fc_shost_template;
static struct fc_function_template bnx2fc_transport_function;
static struct fc_function_template bnx2fc_vport_xport_function;
static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode);
+static void __bnx2fc_destroy(struct bnx2fc_interface *interface, bool schedule);
static int bnx2fc_destroy(struct net_device *net_device);
static int bnx2fc_enable(struct net_device *netdev);
static int bnx2fc_disable(struct net_device *netdev);
@@ -78,6 +79,7 @@ static void bnx2fc_destroy_work(struct work_struct *work);
static struct bnx2fc_hba *bnx2fc_hba_lookup(struct net_device *phys_dev);
static struct bnx2fc_interface *bnx2fc_interface_lookup(struct net_device
*phys_dev);
+static inline void bnx2fc_interface_put(struct bnx2fc_interface *interface);
static struct bnx2fc_hba *bnx2fc_find_hba_for_cnic(struct cnic_dev *cnic);
static int bnx2fc_fw_init(struct bnx2fc_hba *hba);
@@ -783,7 +785,7 @@ static void bnx2fc_destroy_timer(unsigned long data)
* @vlan_id: vlan id - associated vlan id with this event
*
* Handles NETDEV_UP, NETDEV_DOWN, NETDEV_GOING_DOWN,NETDEV_CHANGE and
- * NETDEV_CHANGE_MTU events
+ * NETDEV_CHANGE_MTU events. Handle NETDEV_UNREGISTER only for vlans.
*/
static void bnx2fc_indicate_netevent(void *context, unsigned long event,
u16 vlan_id)
@@ -791,12 +793,11 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event,
struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context;
struct fc_lport *lport;
struct fc_lport *vport;
- struct bnx2fc_interface *interface;
+ struct bnx2fc_interface *interface, *tmp;
int wait_for_upload = 0;
u32 link_possible = 1;
- /* Ignore vlans for now */
- if (vlan_id != 0)
+ if (vlan_id != 0 && event != NETDEV_UNREGISTER)
return;
switch (event) {
@@ -820,6 +821,18 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event,
case NETDEV_CHANGE:
break;
+ case NETDEV_UNREGISTER:
+ if (!vlan_id)
+ return;
+ mutex_lock(&bnx2fc_dev_lock);
+ list_for_each_entry_safe(interface, tmp, &if_list, list) {
+ if (interface->hba != hba)
+ continue;
+ __bnx2fc_destroy(interface, true);
+ }
+ mutex_unlock(&bnx2fc_dev_lock);
+ return;
+
default:
printk(KERN_ERR PFX "Unkonwn netevent %ld", event);
return;
@@ -1022,12 +1035,27 @@ static int bnx2fc_vport_create(struct fc_vport *vport, bool disabled)
return 0;
}
+static void bnx2fc_free_vport(struct bnx2fc_hba *hba, struct fc_lport *lport)
+{
+ struct bnx2fc_lport *blport, *tmp;
+
+ spin_lock_bh(&hba->hba_lock);
+ list_for_each_entry_safe(blport, tmp, &hba->vports, list) {
+ if (blport->lport == lport) {
+ list_del(&blport->list);
+ kfree(blport);
+ }
+ }
+ spin_unlock_bh(&hba->hba_lock);
+}
+
static int bnx2fc_vport_destroy(struct fc_vport *vport)
{
struct Scsi_Host *shost = vport_to_shost(vport);
struct fc_lport *n_port = shost_priv(shost);
struct fc_lport *vn_port = vport->dd_data;
struct fcoe_port *port = lport_priv(vn_port);
+ struct bnx2fc_interface *interface = port->priv;
struct fc_lport *v_port;
bool found = false;
@@ -1044,6 +1072,9 @@ static int bnx2fc_vport_destroy(struct fc_vport *vport)
}
list_del(&vn_port->list);
mutex_unlock(&n_port->lp_mutex);
+ bnx2fc_free_vport(interface->hba, port->lport);
+ bnx2fc_port_shutdown(port->lport);
+ bnx2fc_interface_put(interface);
queue_work(bnx2fc_wq, &port->destroy_work);
return 0;
}
@@ -1386,7 +1417,6 @@ static void bnx2fc_interface_cleanup(struct bnx2fc_interface *interface)
{
struct fc_lport *lport = interface->ctlr.lp;
struct fcoe_port *port = lport_priv(lport);
- struct bnx2fc_lport *blport, *tmp;
struct bnx2fc_hba *hba = interface->hba;
/* Stop the transmit retry timer */
@@ -1400,14 +1430,7 @@ static void bnx2fc_interface_cleanup(struct bnx2fc_interface *interface)
__dev_remove_pack(&interface->fip_packet_type);
synchronize_net();
- spin_lock_bh(&hba->hba_lock);
- list_for_each_entry_safe(blport, tmp, &hba->vports, list) {
- if (blport->lport == lport) {
- list_del(&blport->list);
- kfree(blport);
- }
- }
- spin_unlock_bh(&hba->hba_lock);
+ bnx2fc_free_vport(hba, lport);
}
static void bnx2fc_if_destroy(struct fc_lport *lport)
@@ -1433,6 +1456,23 @@ static void bnx2fc_if_destroy(struct fc_lport *lport)
scsi_host_put(lport->host);
}
+static void __bnx2fc_destroy(struct bnx2fc_interface *interface, bool schedule)
+{
+ struct fc_lport *lport = interface->ctlr.lp;
+ struct fcoe_port *port = lport_priv(lport);
+
+ bnx2fc_interface_cleanup(interface);
+ bnx2fc_stop(interface);
+
+ list_del(&interface->list);
+ lport = interface->ctlr.lp;
+ bnx2fc_interface_put(interface);
+ if (schedule)
+ queue_work(bnx2fc_wq, &port->destroy_work);
+ else
+ bnx2fc_if_destroy(lport);
+}
+
/**
* bnx2fc_destroy - Destroy a bnx2fc FCoE interface
*
@@ -1446,7 +1486,6 @@ static void bnx2fc_if_destroy(struct fc_lport *lport)
static int bnx2fc_destroy(struct net_device *netdev)
{
struct bnx2fc_interface *interface = NULL;
- struct fc_lport *lport;
int rc = 0;
rtnl_lock();
@@ -1460,13 +1499,8 @@ static int bnx2fc_destroy(struct net_device *netdev)
}
- bnx2fc_interface_cleanup(interface);
- lport = interface->ctlr.lp;
- bnx2fc_stop(interface);
- list_del(&interface->list);
destroy_workqueue(interface->timer_work_queue);
- bnx2fc_interface_put(interface);
- bnx2fc_if_destroy(lport);
+ __bnx2fc_destroy(interface, false);
netdev_err:
mutex_unlock(&bnx2fc_dev_lock);
@@ -1478,15 +1512,12 @@ static void bnx2fc_destroy_work(struct work_struct *work)
{
struct fcoe_port *port;
struct fc_lport *lport;
- struct bnx2fc_interface *interface;
port = container_of(work, struct fcoe_port, destroy_work);
lport = port->lport;
- interface = port->priv;
BNX2FC_HBA_DBG(lport, "Entered bnx2fc_destroy_work\n");
- bnx2fc_port_shutdown(lport);
rtnl_lock();
mutex_lock(&bnx2fc_dev_lock);
bnx2fc_if_destroy(lport);
@@ -2031,7 +2062,6 @@ static void bnx2fc_ulp_exit(struct cnic_dev *dev)
{
struct bnx2fc_hba *hba;
struct bnx2fc_interface *interface, *tmp;
- struct fc_lport *lport;
BNX2FC_MISC_DBG("Entered bnx2fc_ulp_exit\n");
@@ -2053,18 +2083,10 @@ static void bnx2fc_ulp_exit(struct cnic_dev *dev)
list_del_init(&hba->list);
adapter_count--;
- list_for_each_entry_safe(interface, tmp, &if_list, list) {
+ list_for_each_entry_safe(interface, tmp, &if_list, list)
/* destroy not called yet, move to quiesced list */
- if (interface->hba == hba) {
- bnx2fc_interface_cleanup(interface);
- bnx2fc_stop(interface);
-
- list_del(&interface->list);
- lport = interface->ctlr.lp;
- bnx2fc_interface_put(interface);
- bnx2fc_if_destroy(lport);
- }
- }
+ if (interface->hba == hba)
+ __bnx2fc_destroy(interface, false);
mutex_unlock(&bnx2fc_dev_lock);
bnx2fc_ulp_stop(hba);
--
1.7.0.6
next prev parent reply other threads:[~2011-08-05 0:39 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-05 0:38 [PATCH v2 00/18] bnx2fc version 1.0.5 Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 01/18] bnx2fc: Reset the max receive frame size Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 02/18] bnx2fc: Bug fixes in percpu_thread_create/destroy Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 03/18] bnx2fc: Enable bsg_request support for bnx2fc Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 04/18] bnx2fc: Remove erroneous kref_get on IO request Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 05/18] bnx2fc: Do not attempt destroying NPIV port twice Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 06/18] bnx2fc: Change function names of bnx2fc_netdev_setup/bnx2fc_netdev_cleanup Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 07/18] bnx2fc: Reorganize cleanup code between interface_cleanup and if_destory Bhanu Prakash Gollapudi
2011-08-05 0:38 ` Bhanu Prakash Gollapudi [this message]
2011-08-05 0:38 ` [PATCH v2 09/18] bnx2fc: Clear DESTROY_CMPL flag after firmware destroy Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 10/18] bnx2fc: Do not reuse the fcoe connection id immediately Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 11/18] bnx2fc: IO errors when receiving unsolicited LOGO Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 12/18] bnx2fc: Fix NULL pointer deref during arm_cq Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 13/18] bnx2fc: code cleanup in bnx2fc_offload_session Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 14/18] bnx2fc: Drop incoming ABTS Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 15/18] fcoe: Move common functions to fcoe_transport library Bhanu Prakash Gollapudi
2011-09-08 11:11 ` Mike Christie
2011-09-08 14:41 ` Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 16/18] bnx2fc: Obtain WWNN/WWPN from the shared memory Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 17/18] bnx2fc: Prevent creating of NPIV port with duplicate WWN Bhanu Prakash Gollapudi
2011-08-05 0:38 ` [PATCH v2 18/18] bnx2fc: Bump version to 1.0.5 Bhanu Prakash Gollapudi
2011-08-24 5:48 ` [PATCH v2 00/18] bnx2fc version 1.0.5 James Bottomley
2011-08-24 18:29 ` Bhanu Prakash Gollapudi
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=1312504732-4572-9-git-send-email-bprakash@broadcom.com \
--to=bprakash@broadcom.com \
--cc=JBottomley@parallels.com \
--cc=devel@open-fcoe.org \
--cc=linux-scsi@vger.kernel.org \
--cc=mchan@broadcom.com \
--cc=michaelc@cs.wisc.edu \
--cc=robert.w.love@intel.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox