Skip to content

Commit f3450c7

Browse files
sswenJames Bottomley
authored andcommitted
[SCSI] zfcp: Replace local reference counting with common kref
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>
1 parent ecf0c77 commit f3450c7

File tree

11 files changed

+196
-258
lines changed

11 files changed

+196
-258
lines changed

drivers/s390/scsi/zfcp_aux.c

Lines changed: 108 additions & 123 deletions
Large diffs are not rendered by default.

drivers/s390/scsi/zfcp_ccw.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,15 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
128128
write_unlock_irq(&adapter->port_list_lock);
129129
mutex_unlock(&zfcp_data.config_mutex);
130130

131-
list_for_each_entry_safe(port, p, &port_remove_lh, list) {
132-
list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
133-
zfcp_unit_dequeue(unit);
134-
zfcp_port_dequeue(port);
135-
}
136-
wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0);
137-
zfcp_adapter_dequeue(adapter);
131+
list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
132+
zfcp_device_unregister(&unit->sysfs_device,
133+
&zfcp_sysfs_unit_attrs);
134+
135+
list_for_each_entry_safe(port, p, &port_remove_lh, list)
136+
zfcp_device_unregister(&port->sysfs_device,
137+
&zfcp_sysfs_port_attrs);
138+
139+
kref_put(&adapter->ref, zfcp_adapter_release);
138140
}
139141

140142
/**

drivers/s390/scsi/zfcp_cfdc.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
9898
if (!adapter)
9999
goto out_put;
100100

101-
zfcp_adapter_get(adapter);
101+
kref_get(&adapter->ref);
102102
out_put:
103103
put_device(&ccwdev->dev);
104104
out:
@@ -212,7 +212,6 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
212212
retval = -ENXIO;
213213
goto free_buffer;
214214
}
215-
zfcp_adapter_get(adapter);
216215

217216
retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg,
218217
data_user->control_file);
@@ -245,7 +244,7 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
245244
free_sg:
246245
zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES);
247246
adapter_put:
248-
zfcp_adapter_put(adapter);
247+
kref_put(&adapter->ref, zfcp_adapter_release);
249248
free_buffer:
250249
kfree(data);
251250
no_mem_sense:

drivers/s390/scsi/zfcp_dbf.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,8 @@ int zfcp_dbf_adapter_register(struct zfcp_adapter *adapter)
10671067
*/
10681068
void zfcp_dbf_adapter_unregister(struct zfcp_dbf *dbf)
10691069
{
1070+
if (!dbf)
1071+
return;
10701072
debug_unregister(dbf->scsi);
10711073
debug_unregister(dbf->san);
10721074
debug_unregister(dbf->hba);

drivers/s390/scsi/zfcp_def.h

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,7 @@ struct zfcp_qdio {
446446
};
447447

448448
struct zfcp_adapter {
449-
atomic_t refcount; /* reference count */
450-
wait_queue_head_t remove_wq; /* can be used to wait for
451-
refcount drop to zero */
449+
struct kref ref;
452450
u64 peer_wwnn; /* P2P peer WWNN */
453451
u64 peer_wwpn; /* P2P peer WWPN */
454452
u32 peer_d_id; /* P2P peer D_ID */
@@ -501,9 +499,6 @@ struct zfcp_port {
501499
struct device sysfs_device; /* sysfs device */
502500
struct fc_rport *rport; /* rport of fc transport class */
503501
struct list_head list; /* list of remote ports */
504-
atomic_t refcount; /* reference count */
505-
wait_queue_head_t remove_wq; /* can be used to wait for
506-
refcount drop to zero */
507502
struct zfcp_adapter *adapter; /* adapter used to access port */
508503
struct list_head unit_list; /* head of logical unit list */
509504
rwlock_t unit_list_lock; /* unit list lock */
@@ -525,9 +520,6 @@ struct zfcp_port {
525520
struct zfcp_unit {
526521
struct device sysfs_device; /* sysfs device */
527522
struct list_head list; /* list of logical units */
528-
atomic_t refcount; /* reference count */
529-
wait_queue_head_t remove_wq; /* can be used to wait for
530-
refcount drop to zero */
531523
struct zfcp_port *port; /* remote port of unit */
532524
atomic_t status; /* status of this logical unit */
533525
u64 fcp_lun; /* own FCP_LUN */
@@ -656,47 +648,4 @@ zfcp_reqlist_find_safe(struct zfcp_adapter *adapter, struct zfcp_fsf_req *req)
656648
return NULL;
657649
}
658650

659-
/*
660-
* functions needed for reference/usage counting
661-
*/
662-
663-
static inline void
664-
zfcp_unit_get(struct zfcp_unit *unit)
665-
{
666-
atomic_inc(&unit->refcount);
667-
}
668-
669-
static inline void
670-
zfcp_unit_put(struct zfcp_unit *unit)
671-
{
672-
if (atomic_dec_return(&unit->refcount) == 0)
673-
wake_up(&unit->remove_wq);
674-
}
675-
676-
static inline void
677-
zfcp_port_get(struct zfcp_port *port)
678-
{
679-
atomic_inc(&port->refcount);
680-
}
681-
682-
static inline void
683-
zfcp_port_put(struct zfcp_port *port)
684-
{
685-
if (atomic_dec_return(&port->refcount) == 0)
686-
wake_up(&port->remove_wq);
687-
}
688-
689-
static inline void
690-
zfcp_adapter_get(struct zfcp_adapter *adapter)
691-
{
692-
atomic_inc(&adapter->refcount);
693-
}
694-
695-
static inline void
696-
zfcp_adapter_put(struct zfcp_adapter *adapter)
697-
{
698-
if (atomic_dec_return(&adapter->refcount) == 0)
699-
wake_up(&adapter->remove_wq);
700-
}
701-
702651
#endif /* ZFCP_DEF_H */

drivers/s390/scsi/zfcp_erp.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
174174

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

184184
case ZFCP_ERP_ACTION_REOPEN_PORT:
185185
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
186-
zfcp_port_get(port);
186+
get_device(&port->sysfs_device);
187187
zfcp_erp_action_dismiss_port(port);
188188
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
189189
erp_action = &port->erp_action;
@@ -192,7 +192,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
192192
break;
193193

194194
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
195-
zfcp_adapter_get(adapter);
195+
kref_get(&adapter->ref);
196196
zfcp_erp_action_dismiss_adapter(adapter);
197197
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
198198
erp_action = &adapter->erp_action;
@@ -1177,19 +1177,19 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
11771177
switch (act->action) {
11781178
case ZFCP_ERP_ACTION_REOPEN_UNIT:
11791179
if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) {
1180-
zfcp_unit_get(unit);
1180+
get_device(&unit->sysfs_device);
11811181
if (scsi_queue_work(unit->port->adapter->scsi_host,
11821182
&unit->scsi_work) <= 0)
1183-
zfcp_unit_put(unit);
1183+
put_device(&unit->sysfs_device);
11841184
}
1185-
zfcp_unit_put(unit);
1185+
put_device(&unit->sysfs_device);
11861186
break;
11871187

11881188
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
11891189
case ZFCP_ERP_ACTION_REOPEN_PORT:
11901190
if (result == ZFCP_ERP_SUCCEEDED)
11911191
zfcp_scsi_schedule_rport_register(port);
1192-
zfcp_port_put(port);
1192+
put_device(&port->sysfs_device);
11931193
break;
11941194

11951195
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
@@ -1198,7 +1198,7 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
11981198
schedule_work(&adapter->scan_work);
11991199
} else
12001200
unregister_service_level(&adapter->service_level);
1201-
zfcp_adapter_put(adapter);
1201+
kref_put(&adapter->ref, zfcp_adapter_release);
12021202
break;
12031203
}
12041204
}
@@ -1224,8 +1224,9 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
12241224
unsigned long flags;
12251225
struct zfcp_adapter *adapter = erp_action->adapter;
12261226

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

1229+
write_lock_irqsave(&adapter->erp_lock, flags);
12291230
zfcp_erp_strategy_check_fsfreq(erp_action);
12301231

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

1286+
kref_put(&adapter->ref, zfcp_adapter_release);
12851287
return retval;
12861288
}
12871289

drivers/s390/scsi/zfcp_ext.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@
1515
extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, u64);
1616
extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, u64);
1717
extern int zfcp_adapter_enqueue(struct ccw_device *);
18-
extern void zfcp_adapter_dequeue(struct zfcp_adapter *);
1918
extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32,
2019
u32);
21-
extern void zfcp_port_dequeue(struct zfcp_port *);
2220
extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, u64);
23-
extern void zfcp_unit_dequeue(struct zfcp_unit *);
2421
extern int zfcp_reqlist_isempty(struct zfcp_adapter *);
2522
extern void zfcp_sg_free_table(struct scatterlist *, int);
2623
extern int zfcp_sg_setup_table(struct scatterlist *, int);
24+
extern void zfcp_device_unregister(struct device *,
25+
const struct attribute_group *);
26+
extern void zfcp_adapter_release(struct kref *);
2727

2828
/* zfcp_ccw.c */
2929
extern int zfcp_ccw_register(void);

drivers/s390/scsi/zfcp_fc.c

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ static void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *wka)
134134

135135
void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *gs)
136136
{
137+
if (!gs)
138+
return;
137139
zfcp_fc_wka_port_force_offline(&gs->ms);
138140
zfcp_fc_wka_port_force_offline(&gs->ts);
139141
zfcp_fc_wka_port_force_offline(&gs->ds);
@@ -356,7 +358,7 @@ void zfcp_fc_port_did_lookup(struct work_struct *work)
356358

357359
zfcp_erp_port_reopen(port, 0, "fcgpn_3", NULL);
358360
out:
359-
zfcp_port_put(port);
361+
put_device(&port->sysfs_device);
360362
}
361363

362364
/**
@@ -365,9 +367,9 @@ void zfcp_fc_port_did_lookup(struct work_struct *work)
365367
*/
366368
void zfcp_fc_trigger_did_lookup(struct zfcp_port *port)
367369
{
368-
zfcp_port_get(port);
370+
get_device(&port->sysfs_device);
369371
if (!queue_work(port->adapter->work_queue, &port->gid_pn_work))
370-
zfcp_port_put(port);
372+
put_device(&port->sysfs_device);
371373
}
372374

373375
/**
@@ -426,7 +428,7 @@ static void zfcp_fc_adisc_handler(unsigned long data)
426428
zfcp_scsi_schedule_rport_register(port);
427429
out:
428430
atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
429-
zfcp_port_put(port);
431+
put_device(&port->sysfs_device);
430432
kfree(adisc);
431433
}
432434

@@ -468,7 +470,7 @@ void zfcp_fc_link_test_work(struct work_struct *work)
468470
container_of(work, struct zfcp_port, test_link_work);
469471
int retval;
470472

471-
zfcp_port_get(port);
473+
get_device(&port->sysfs_device);
472474
port->rport_task = RPORT_DEL;
473475
zfcp_scsi_rport_work(&port->rport_work);
474476

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

489491
out:
490-
zfcp_port_put(port);
492+
put_device(&port->sysfs_device);
491493
}
492494

493495
/**
@@ -500,9 +502,9 @@ void zfcp_fc_link_test_work(struct work_struct *work)
500502
*/
501503
void zfcp_fc_test_link(struct zfcp_port *port)
502504
{
503-
zfcp_port_get(port);
505+
get_device(&port->sysfs_device);
504506
if (!queue_work(port->adapter->work_queue, &port->test_link_work))
505-
zfcp_port_put(port);
507+
put_device(&port->sysfs_device);
506508
}
507509

508510
static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num)
@@ -576,21 +578,19 @@ static int zfcp_fc_send_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
576578
return ret;
577579
}
578580

579-
static void zfcp_fc_validate_port(struct zfcp_port *port)
581+
static void zfcp_fc_validate_port(struct zfcp_port *port, struct list_head *lh)
580582
{
581583
if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC))
582584
return;
583585

584586
atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status);
585587

586588
if ((port->supported_classes != 0) ||
587-
!list_empty(&port->unit_list)) {
588-
zfcp_port_put(port);
589+
!list_empty(&port->unit_list))
589590
return;
590-
}
591-
zfcp_erp_port_shutdown(port, 0, "fcpval1", NULL);
592-
zfcp_port_put(port);
593-
zfcp_port_dequeue(port);
591+
592+
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
593+
list_move_tail(&port->list, lh);
594594
}
595595

596596
static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
@@ -602,6 +602,7 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
602602
struct zfcp_adapter *adapter = ct->wka_port->adapter;
603603
struct zfcp_port *port, *tmp;
604604
unsigned long flags;
605+
LIST_HEAD(remove_lh);
605606
u32 d_id;
606607
int ret = 0, x, last = 0;
607608

@@ -652,9 +653,16 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
652653
zfcp_erp_wait(adapter);
653654
write_lock_irqsave(&adapter->port_list_lock, flags);
654655
list_for_each_entry_safe(port, tmp, &adapter->port_list, list)
655-
zfcp_fc_validate_port(port);
656+
zfcp_fc_validate_port(port, &remove_lh);
656657
write_unlock_irqrestore(&adapter->port_list_lock, flags);
657658
mutex_unlock(&zfcp_data.config_mutex);
659+
660+
list_for_each_entry_safe(port, tmp, &remove_lh, list) {
661+
zfcp_erp_port_shutdown(port, 0, "fcegpf2", NULL);
662+
zfcp_device_unregister(&port->sysfs_device,
663+
&zfcp_sysfs_port_attrs);
664+
}
665+
658666
return ret;
659667
}
660668

@@ -763,7 +771,7 @@ int zfcp_fc_execute_els_fc_job(struct fc_bsg_job *job)
763771
}
764772

765773
els_fc_job->els.d_id = port->d_id;
766-
zfcp_port_put(port);
774+
put_device(&port->sysfs_device);
767775
} else {
768776
port_did = job->request->rqst_data.h_els.port_id;
769777
els_fc_job->els.d_id = (port_did[0] << 16) +

0 commit comments

Comments
 (0)