Skip to content

Commit

Permalink
[SCSI] zfcp: Replace local reference counting with common kref
Browse files Browse the repository at this point in the history
Replace the local reference counting by already available mechanisms
offered by kref. Where possible existing device structures were used,
including the same functionality.

Signed-off-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
  • Loading branch information
sswen authored and James Bottomley committed Dec 4, 2009
1 parent ecf0c77 commit f3450c7
Show file tree
Hide file tree
Showing 11 changed files with 196 additions and 258 deletions.
231 changes: 108 additions & 123 deletions drivers/s390/scsi/zfcp_aux.c

Large diffs are not rendered by default.

16 changes: 9 additions & 7 deletions drivers/s390/scsi/zfcp_ccw.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,15 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
write_unlock_irq(&adapter->port_list_lock);
mutex_unlock(&zfcp_data.config_mutex);

list_for_each_entry_safe(port, p, &port_remove_lh, list) {
list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
zfcp_unit_dequeue(unit);
zfcp_port_dequeue(port);
}
wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0);
zfcp_adapter_dequeue(adapter);
list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
zfcp_device_unregister(&unit->sysfs_device,
&zfcp_sysfs_unit_attrs);

list_for_each_entry_safe(port, p, &port_remove_lh, list)
zfcp_device_unregister(&port->sysfs_device,
&zfcp_sysfs_port_attrs);

kref_put(&adapter->ref, zfcp_adapter_release);
}

/**
Expand Down
5 changes: 2 additions & 3 deletions drivers/s390/scsi/zfcp_cfdc.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
if (!adapter)
goto out_put;

zfcp_adapter_get(adapter);
kref_get(&adapter->ref);
out_put:
put_device(&ccwdev->dev);
out:
Expand Down Expand Up @@ -212,7 +212,6 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
retval = -ENXIO;
goto free_buffer;
}
zfcp_adapter_get(adapter);

retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg,
data_user->control_file);
Expand Down Expand Up @@ -245,7 +244,7 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
free_sg:
zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES);
adapter_put:
zfcp_adapter_put(adapter);
kref_put(&adapter->ref, zfcp_adapter_release);
free_buffer:
kfree(data);
no_mem_sense:
Expand Down
2 changes: 2 additions & 0 deletions drivers/s390/scsi/zfcp_dbf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,8 @@ int zfcp_dbf_adapter_register(struct zfcp_adapter *adapter)
*/
void zfcp_dbf_adapter_unregister(struct zfcp_dbf *dbf)
{
if (!dbf)
return;
debug_unregister(dbf->scsi);
debug_unregister(dbf->san);
debug_unregister(dbf->hba);
Expand Down
53 changes: 1 addition & 52 deletions drivers/s390/scsi/zfcp_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -446,9 +446,7 @@ struct zfcp_qdio {
};

struct zfcp_adapter {
atomic_t refcount; /* reference count */
wait_queue_head_t remove_wq; /* can be used to wait for
refcount drop to zero */
struct kref ref;
u64 peer_wwnn; /* P2P peer WWNN */
u64 peer_wwpn; /* P2P peer WWPN */
u32 peer_d_id; /* P2P peer D_ID */
Expand Down Expand Up @@ -501,9 +499,6 @@ struct zfcp_port {
struct device sysfs_device; /* sysfs device */
struct fc_rport *rport; /* rport of fc transport class */
struct list_head list; /* list of remote ports */
atomic_t refcount; /* reference count */
wait_queue_head_t remove_wq; /* can be used to wait for
refcount drop to zero */
struct zfcp_adapter *adapter; /* adapter used to access port */
struct list_head unit_list; /* head of logical unit list */
rwlock_t unit_list_lock; /* unit list lock */
Expand All @@ -525,9 +520,6 @@ struct zfcp_port {
struct zfcp_unit {
struct device sysfs_device; /* sysfs device */
struct list_head list; /* list of logical units */
atomic_t refcount; /* reference count */
wait_queue_head_t remove_wq; /* can be used to wait for
refcount drop to zero */
struct zfcp_port *port; /* remote port of unit */
atomic_t status; /* status of this logical unit */
u64 fcp_lun; /* own FCP_LUN */
Expand Down Expand Up @@ -656,47 +648,4 @@ zfcp_reqlist_find_safe(struct zfcp_adapter *adapter, struct zfcp_fsf_req *req)
return NULL;
}

/*
* functions needed for reference/usage counting
*/

static inline void
zfcp_unit_get(struct zfcp_unit *unit)
{
atomic_inc(&unit->refcount);
}

static inline void
zfcp_unit_put(struct zfcp_unit *unit)
{
if (atomic_dec_return(&unit->refcount) == 0)
wake_up(&unit->remove_wq);
}

static inline void
zfcp_port_get(struct zfcp_port *port)
{
atomic_inc(&port->refcount);
}

static inline void
zfcp_port_put(struct zfcp_port *port)
{
if (atomic_dec_return(&port->refcount) == 0)
wake_up(&port->remove_wq);
}

static inline void
zfcp_adapter_get(struct zfcp_adapter *adapter)
{
atomic_inc(&adapter->refcount);
}

static inline void
zfcp_adapter_put(struct zfcp_adapter *adapter)
{
if (atomic_dec_return(&adapter->refcount) == 0)
wake_up(&adapter->remove_wq);
}

#endif /* ZFCP_DEF_H */
20 changes: 11 additions & 9 deletions drivers/s390/scsi/zfcp_erp.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,

switch (need) {
case ZFCP_ERP_ACTION_REOPEN_UNIT:
zfcp_unit_get(unit);
get_device(&unit->sysfs_device);
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status);
erp_action = &unit->erp_action;
if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING))
Expand All @@ -183,7 +183,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,

case ZFCP_ERP_ACTION_REOPEN_PORT:
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
zfcp_port_get(port);
get_device(&port->sysfs_device);
zfcp_erp_action_dismiss_port(port);
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
erp_action = &port->erp_action;
Expand All @@ -192,7 +192,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
break;

case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
zfcp_adapter_get(adapter);
kref_get(&adapter->ref);
zfcp_erp_action_dismiss_adapter(adapter);
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
erp_action = &adapter->erp_action;
Expand Down Expand Up @@ -1177,19 +1177,19 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
switch (act->action) {
case ZFCP_ERP_ACTION_REOPEN_UNIT:
if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) {
zfcp_unit_get(unit);
get_device(&unit->sysfs_device);
if (scsi_queue_work(unit->port->adapter->scsi_host,
&unit->scsi_work) <= 0)
zfcp_unit_put(unit);
put_device(&unit->sysfs_device);
}
zfcp_unit_put(unit);
put_device(&unit->sysfs_device);
break;

case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
case ZFCP_ERP_ACTION_REOPEN_PORT:
if (result == ZFCP_ERP_SUCCEEDED)
zfcp_scsi_schedule_rport_register(port);
zfcp_port_put(port);
put_device(&port->sysfs_device);
break;

case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
Expand All @@ -1198,7 +1198,7 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
schedule_work(&adapter->scan_work);
} else
unregister_service_level(&adapter->service_level);
zfcp_adapter_put(adapter);
kref_put(&adapter->ref, zfcp_adapter_release);
break;
}
}
Expand All @@ -1224,8 +1224,9 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
unsigned long flags;
struct zfcp_adapter *adapter = erp_action->adapter;

write_lock_irqsave(&adapter->erp_lock, flags);
kref_get(&adapter->ref);

write_lock_irqsave(&adapter->erp_lock, flags);
zfcp_erp_strategy_check_fsfreq(erp_action);

if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) {
Expand Down Expand Up @@ -1282,6 +1283,7 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
if (retval != ZFCP_ERP_CONTINUES)
zfcp_erp_action_cleanup(erp_action, retval);

kref_put(&adapter->ref, zfcp_adapter_release);
return retval;
}

Expand Down
6 changes: 3 additions & 3 deletions drivers/s390/scsi/zfcp_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@
extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, u64);
extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, u64);
extern int zfcp_adapter_enqueue(struct ccw_device *);
extern void zfcp_adapter_dequeue(struct zfcp_adapter *);
extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32,
u32);
extern void zfcp_port_dequeue(struct zfcp_port *);
extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, u64);
extern void zfcp_unit_dequeue(struct zfcp_unit *);
extern int zfcp_reqlist_isempty(struct zfcp_adapter *);
extern void zfcp_sg_free_table(struct scatterlist *, int);
extern int zfcp_sg_setup_table(struct scatterlist *, int);
extern void zfcp_device_unregister(struct device *,
const struct attribute_group *);
extern void zfcp_adapter_release(struct kref *);

/* zfcp_ccw.c */
extern int zfcp_ccw_register(void);
Expand Down
42 changes: 25 additions & 17 deletions drivers/s390/scsi/zfcp_fc.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ static void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *wka)

void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *gs)
{
if (!gs)
return;
zfcp_fc_wka_port_force_offline(&gs->ms);
zfcp_fc_wka_port_force_offline(&gs->ts);
zfcp_fc_wka_port_force_offline(&gs->ds);
Expand Down Expand Up @@ -356,7 +358,7 @@ void zfcp_fc_port_did_lookup(struct work_struct *work)

zfcp_erp_port_reopen(port, 0, "fcgpn_3", NULL);
out:
zfcp_port_put(port);
put_device(&port->sysfs_device);
}

/**
Expand All @@ -365,9 +367,9 @@ void zfcp_fc_port_did_lookup(struct work_struct *work)
*/
void zfcp_fc_trigger_did_lookup(struct zfcp_port *port)
{
zfcp_port_get(port);
get_device(&port->sysfs_device);
if (!queue_work(port->adapter->work_queue, &port->gid_pn_work))
zfcp_port_put(port);
put_device(&port->sysfs_device);
}

/**
Expand Down Expand Up @@ -426,7 +428,7 @@ static void zfcp_fc_adisc_handler(unsigned long data)
zfcp_scsi_schedule_rport_register(port);
out:
atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
zfcp_port_put(port);
put_device(&port->sysfs_device);
kfree(adisc);
}

Expand Down Expand Up @@ -468,7 +470,7 @@ void zfcp_fc_link_test_work(struct work_struct *work)
container_of(work, struct zfcp_port, test_link_work);
int retval;

zfcp_port_get(port);
get_device(&port->sysfs_device);
port->rport_task = RPORT_DEL;
zfcp_scsi_rport_work(&port->rport_work);

Expand All @@ -487,7 +489,7 @@ void zfcp_fc_link_test_work(struct work_struct *work)
zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL);

out:
zfcp_port_put(port);
put_device(&port->sysfs_device);
}

/**
Expand All @@ -500,9 +502,9 @@ void zfcp_fc_link_test_work(struct work_struct *work)
*/
void zfcp_fc_test_link(struct zfcp_port *port)
{
zfcp_port_get(port);
get_device(&port->sysfs_device);
if (!queue_work(port->adapter->work_queue, &port->test_link_work))
zfcp_port_put(port);
put_device(&port->sysfs_device);
}

static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num)
Expand Down Expand Up @@ -576,21 +578,19 @@ static int zfcp_fc_send_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
return ret;
}

static void zfcp_fc_validate_port(struct zfcp_port *port)
static void zfcp_fc_validate_port(struct zfcp_port *port, struct list_head *lh)
{
if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC))
return;

atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status);

if ((port->supported_classes != 0) ||
!list_empty(&port->unit_list)) {
zfcp_port_put(port);
!list_empty(&port->unit_list))
return;
}
zfcp_erp_port_shutdown(port, 0, "fcpval1", NULL);
zfcp_port_put(port);
zfcp_port_dequeue(port);

atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
list_move_tail(&port->list, lh);
}

static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
Expand All @@ -602,6 +602,7 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
struct zfcp_adapter *adapter = ct->wka_port->adapter;
struct zfcp_port *port, *tmp;
unsigned long flags;
LIST_HEAD(remove_lh);
u32 d_id;
int ret = 0, x, last = 0;

Expand Down Expand Up @@ -652,9 +653,16 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
zfcp_erp_wait(adapter);
write_lock_irqsave(&adapter->port_list_lock, flags);
list_for_each_entry_safe(port, tmp, &adapter->port_list, list)
zfcp_fc_validate_port(port);
zfcp_fc_validate_port(port, &remove_lh);
write_unlock_irqrestore(&adapter->port_list_lock, flags);
mutex_unlock(&zfcp_data.config_mutex);

list_for_each_entry_safe(port, tmp, &remove_lh, list) {
zfcp_erp_port_shutdown(port, 0, "fcegpf2", NULL);
zfcp_device_unregister(&port->sysfs_device,
&zfcp_sysfs_port_attrs);
}

return ret;
}

Expand Down Expand Up @@ -763,7 +771,7 @@ int zfcp_fc_execute_els_fc_job(struct fc_bsg_job *job)
}

els_fc_job->els.d_id = port->d_id;
zfcp_port_put(port);
put_device(&port->sysfs_device);
} else {
port_did = job->request->rqst_data.h_els.port_id;
els_fc_job->els.d_id = (port_did[0] << 16) +
Expand Down
Loading

0 comments on commit f3450c7

Please sign in to comment.