We need to be better about reference counting. The first
step is to make use of the release function that is called
when the reference count drops to 0.
There was some inital push back by Joe on this patch. We
talked off-list and agreed that the benefit of not having
to check whether a rport is rogue or real overweighed the
fact that we might be using reference counting on objects
(rogue) that cannot be acted on by another thread.
There is likely room for improvement here, but this should
be a stable start.
Signed-off-by: Robert Love <[EMAIL PROTECTED]>
---
drivers/scsi/libfc/fc_rport.c | 18 +++++++++++-------
include/scsi/libfc.h | 1 -
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 5e07adf..4272196 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -90,6 +90,13 @@ static const char *fc_rport_state_names[] = {
[RPORT_ST_LOGO] = "LOGO",
};
+static void fc_rport_rogue_destroy(struct device *dev)
+{
+ struct fc_rport *rport = dev_to_rport(dev);
+ FC_DEBUG_RPORT("Destroying rogue rport (%6x)\n", rport->port_id);
+ kfree(rport);
+}
+
struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *dp)
{
struct fc_rport *rport;
@@ -117,6 +124,8 @@ struct fc_rport *fc_rport_rogue_create(struct fc_disc_port
*dp)
* upstream so it fine that this is really ugly and hacky right now.
*/
device_initialize(&rport->dev);
+ rport->dev.release = fc_rport_rogue_destroy;
+
get_device(&rport->dev);
mutex_init(&rdata->rp_mutex);
@@ -139,11 +148,6 @@ struct fc_rport *fc_rport_rogue_create(struct fc_disc_port
*dp)
return rport;
}
-void fc_rport_rogue_destroy(struct fc_rport *rport)
-{
- kfree(rport);
-}
-
/**
* fc_rport_state - return a string for the state the rport is in
* @rport: The rport whose state we want to get a string for
@@ -265,7 +269,7 @@ static void fc_rport_work(struct work_struct *work)
"(%6x).\n", ids.port_id);
event = RPORT_EV_FAILED;
}
- fc_rport_rogue_destroy(rport);
+ put_device(&rport->dev);
rport = new_rport;
rdata = new_rport->dd_data;
if (rport_ops->event_callback)
@@ -278,7 +282,7 @@ static void fc_rport_work(struct work_struct *work)
if (rport_ops->event_callback)
rport_ops->event_callback(lport, rport, event);
if (trans_state == FC_PORTSTATE_ROGUE)
- fc_rport_rogue_destroy(rport);
+ put_device(&rport->dev);
else
fc_remote_port_delete(rport);
} else
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 9632898..086573a 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -169,7 +169,6 @@ struct fc_rport_libfc_priv {
(struct fc_rport_libfc_priv *)((void *)x + sizeof(struct fc_rport));
struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *);
-void fc_rport_rogue_destroy(struct fc_rport *);
static inline void fc_rport_set_name(struct fc_rport *rport, u64 wwpn, u64
wwnn)
{
_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel