Skip to content

Commit fdbd1c5

Browse files
Christof SchmittJames Bottomley
Christof Schmitt
authored and
James Bottomley
committed
[SCSI] zfcp: Allow running unit/LUN shutdown without acquiring reference
With the change for the LUN data to be part of the scsi_device, the slave_destroy callback will be the final call to the zfcp_erp_unit_shutdown function. The erp tries to acquire a reference to run the action asynchronously and fail, if it cannot get the reference. But calling scsi_device_get from slave_destroy will fail, because the scsi_device is already in the state SDEV_DEL. Introduce a new call into the zfcp erp to solve this: The function zfcp_erp_unit_shutdown_wait will close the LUN and wait for the erp to finish without acquiring an additional reference. The wait allows to omit the reference; the caller waiting for the erp to finish already has a reference that holds the struct in place. Reviewed-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 e4b9857 commit fdbd1c5

File tree

2 files changed

+63
-36
lines changed

2 files changed

+63
-36
lines changed

drivers/s390/scsi/zfcp_erp.c

+62-36
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ enum zfcp_erp_act_flags {
2121
ZFCP_STATUS_ERP_DISMISSING = 0x00100000,
2222
ZFCP_STATUS_ERP_DISMISSED = 0x00200000,
2323
ZFCP_STATUS_ERP_LOWMEM = 0x00400000,
24+
ZFCP_STATUS_ERP_NO_REF = 0x00800000,
2425
};
2526

2627
enum zfcp_erp_steps {
@@ -169,22 +170,22 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
169170
return need;
170171
}
171172

172-
static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
173+
static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
173174
struct zfcp_adapter *adapter,
174175
struct zfcp_port *port,
175176
struct zfcp_unit *unit)
176177
{
177178
struct zfcp_erp_action *erp_action;
178-
u32 status = 0;
179179

180180
switch (need) {
181181
case ZFCP_ERP_ACTION_REOPEN_UNIT:
182-
if (!get_device(&unit->dev))
183-
return NULL;
182+
if (!(act_status & ZFCP_STATUS_ERP_NO_REF))
183+
if (!get_device(&unit->dev))
184+
return NULL;
184185
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status);
185186
erp_action = &unit->erp_action;
186187
if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING))
187-
status = ZFCP_STATUS_ERP_CLOSE_ONLY;
188+
act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
188189
break;
189190

190191
case ZFCP_ERP_ACTION_REOPEN_PORT:
@@ -195,7 +196,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
195196
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
196197
erp_action = &port->erp_action;
197198
if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING))
198-
status = ZFCP_STATUS_ERP_CLOSE_ONLY;
199+
act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
199200
break;
200201

201202
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
@@ -205,7 +206,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
205206
erp_action = &adapter->erp_action;
206207
if (!(atomic_read(&adapter->status) &
207208
ZFCP_STATUS_COMMON_RUNNING))
208-
status = ZFCP_STATUS_ERP_CLOSE_ONLY;
209+
act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
209210
break;
210211

211212
default:
@@ -217,14 +218,15 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
217218
erp_action->port = port;
218219
erp_action->unit = unit;
219220
erp_action->action = need;
220-
erp_action->status = status;
221+
erp_action->status = act_status;
221222

222223
return erp_action;
223224
}
224225

225226
static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
226227
struct zfcp_port *port,
227-
struct zfcp_unit *unit, char *id, void *ref)
228+
struct zfcp_unit *unit, char *id, void *ref,
229+
u32 act_status)
228230
{
229231
int retval = 1, need;
230232
struct zfcp_erp_action *act = NULL;
@@ -236,10 +238,10 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
236238
if (!need)
237239
goto out;
238240

239-
atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status);
240-
act = zfcp_erp_setup_act(need, adapter, port, unit);
241+
act = zfcp_erp_setup_act(need, act_status, adapter, port, unit);
241242
if (!act)
242243
goto out;
244+
atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status);
243245
++adapter->erp_total_count;
244246
list_add_tail(&act->list, &adapter->erp_ready_head);
245247
wake_up(&adapter->erp_ready_wq);
@@ -262,7 +264,7 @@ static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
262264
return -EIO;
263265
}
264266
return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER,
265-
adapter, NULL, NULL, id, ref);
267+
adapter, NULL, NULL, id, ref, 0);
266268
}
267269

268270
/**
@@ -285,7 +287,7 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
285287
zfcp_erp_adapter_failed(adapter, "erareo1", NULL);
286288
else
287289
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter,
288-
NULL, NULL, id, ref);
290+
NULL, NULL, id, ref, 0);
289291
write_unlock_irqrestore(&adapter->erp_lock, flags);
290292
}
291293

@@ -317,20 +319,6 @@ void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *id,
317319
zfcp_erp_port_reopen(port, clear | flags, id, ref);
318320
}
319321

320-
/**
321-
* zfcp_erp_unit_shutdown - Shutdown unit
322-
* @unit: Unit to shut down.
323-
* @clear: Status flags to clear.
324-
* @id: Id for debug trace event.
325-
* @ref: Reference for debug trace event.
326-
*/
327-
void zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear, char *id,
328-
void *ref)
329-
{
330-
int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
331-
zfcp_erp_unit_reopen(unit, clear | flags, id, ref);
332-
}
333-
334322
static void zfcp_erp_port_block(struct zfcp_port *port, int clear)
335323
{
336324
zfcp_erp_modify_port_status(port, "erpblk1", NULL,
@@ -348,7 +336,7 @@ static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port,
348336
return;
349337

350338
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
351-
port->adapter, port, NULL, id, ref);
339+
port->adapter, port, NULL, id, ref, 0);
352340
}
353341

354342
/**
@@ -381,7 +369,7 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id,
381369
}
382370

383371
return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT,
384-
port->adapter, port, NULL, id, ref);
372+
port->adapter, port, NULL, id, ref, 0);
385373
}
386374

387375
/**
@@ -412,7 +400,7 @@ static void zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask)
412400
}
413401

414402
static void _zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id,
415-
void *ref)
403+
void *ref, u32 act_status)
416404
{
417405
struct zfcp_adapter *adapter = unit->port->adapter;
418406

@@ -422,7 +410,7 @@ static void _zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id,
422410
return;
423411

424412
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_UNIT,
425-
adapter, unit->port, unit, id, ref);
413+
adapter, unit->port, unit, id, ref, act_status);
426414
}
427415

428416
/**
@@ -439,8 +427,45 @@ void zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id,
439427
struct zfcp_adapter *adapter = port->adapter;
440428

441429
write_lock_irqsave(&adapter->erp_lock, flags);
442-
_zfcp_erp_unit_reopen(unit, clear, id, ref);
430+
_zfcp_erp_unit_reopen(unit, clear, id, ref, 0);
431+
write_unlock_irqrestore(&adapter->erp_lock, flags);
432+
}
433+
434+
/**
435+
* zfcp_erp_unit_shutdown - Shutdown unit
436+
* @unit: Unit to shut down.
437+
* @clear: Status flags to clear.
438+
* @id: Id for debug trace event.
439+
* @ref: Reference for debug trace event.
440+
*/
441+
void zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear, char *id,
442+
void *ref)
443+
{
444+
int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
445+
zfcp_erp_unit_reopen(unit, clear | flags, id, ref);
446+
}
447+
448+
/**
449+
* zfcp_erp_unit_shutdown_wait - Shutdown unit and wait for erp completion
450+
* @unit: Unit to shut down.
451+
* @id: Id for debug trace event.
452+
*
453+
* Do not acquire a reference for the unit when creating the ERP
454+
* action. It is safe, because this function waits for the ERP to
455+
* complete first.
456+
*/
457+
void zfcp_erp_unit_shutdown_wait(struct zfcp_unit *unit, char *id)
458+
{
459+
unsigned long flags;
460+
struct zfcp_port *port = unit->port;
461+
struct zfcp_adapter *adapter = port->adapter;
462+
int clear = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
463+
464+
write_lock_irqsave(&adapter->erp_lock, flags);
465+
_zfcp_erp_unit_reopen(unit, clear, id, NULL, ZFCP_STATUS_ERP_NO_REF);
443466
write_unlock_irqrestore(&adapter->erp_lock, flags);
467+
468+
zfcp_erp_wait(adapter);
444469
}
445470

446471
static int status_change_set(unsigned long mask, atomic_t *status)
@@ -566,7 +591,7 @@ static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear,
566591

567592
read_lock(&port->unit_list_lock);
568593
list_for_each_entry(unit, &port->unit_list, list)
569-
_zfcp_erp_unit_reopen(unit, clear, id, ref);
594+
_zfcp_erp_unit_reopen(unit, clear, id, ref, 0);
570595
read_unlock(&port->unit_list_lock);
571596
}
572597

@@ -583,7 +608,7 @@ static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act)
583608
_zfcp_erp_port_reopen(act->port, 0, "ersff_3", NULL);
584609
break;
585610
case ZFCP_ERP_ACTION_REOPEN_UNIT:
586-
_zfcp_erp_unit_reopen(act->unit, 0, "ersff_4", NULL);
611+
_zfcp_erp_unit_reopen(act->unit, 0, "ersff_4", NULL, 0);
587612
break;
588613
}
589614
}
@@ -1143,7 +1168,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
11431168
if (zfcp_erp_strat_change_det(&unit->status, erp_status)) {
11441169
_zfcp_erp_unit_reopen(unit,
11451170
ZFCP_STATUS_COMMON_ERP_FAILED,
1146-
"ersscg3", NULL);
1171+
"ersscg3", NULL, 0);
11471172
return ZFCP_ERP_EXIT;
11481173
}
11491174
break;
@@ -1191,7 +1216,8 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
11911216

11921217
switch (act->action) {
11931218
case ZFCP_ERP_ACTION_REOPEN_UNIT:
1194-
put_device(&unit->dev);
1219+
if (!(act->status & ZFCP_STATUS_ERP_NO_REF))
1220+
put_device(&unit->dev);
11951221
break;
11961222

11971223
case ZFCP_ERP_ACTION_REOPEN_PORT:

drivers/s390/scsi/zfcp_ext.h

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, char *, void *, u32,
8080
int);
8181
extern void zfcp_erp_unit_reopen(struct zfcp_unit *, int, char *, void *);
8282
extern void zfcp_erp_unit_shutdown(struct zfcp_unit *, int, char *, void *);
83+
extern void zfcp_erp_unit_shutdown_wait(struct zfcp_unit *, char *);
8384
extern void zfcp_erp_unit_failed(struct zfcp_unit *, char *, void *);
8485
extern int zfcp_erp_thread_setup(struct zfcp_adapter *);
8586
extern void zfcp_erp_thread_kill(struct zfcp_adapter *);

0 commit comments

Comments
 (0)