mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-21 11:44:01 +08:00
cxlflash: Fix to drain operations from previous reset
While running 'sg_reset -H' in a loop with a user-space application active, hit the following exception: cpu 0x2: Vector: 300 (Data Access) pc: : afu_attach+0x50/0x240 [cxlflash] lr: : cxlflash_afu_recover+0x3dc/0x7d0 [cxlflash] pid = 20365, comm = run_block_fvt Linux version 4.5.0-491-26f710d+ cxlflash_afu_recover+0x3dc/0x7d0 [cxlflash] cxlflash_ioctl+0x5a8/0x6f0 [cxlflash] scsi_ioctl+0x3b0/0x4c0 sd_ioctl+0x110/0x190 blkdev_ioctl+0x28c/0xc20 block_ioctl+0xa4/0xd0 do_vfs_ioctl+0xd8/0x8c0 SyS_ioctl+0xd4/0xf0 system_call+0x38/0xb4 The problem here is that the problem space area is unmapped while the application issues the DK_CXLFLASH_RECOVER_AFU ioctl. This is the order I observe: proc1 proc2 1) sg_reset 2) ioctl(DK_CXLFLASH_RECOVER_AFU) 3) sg_reset again causing a PSA unmap 4) continues RECOVER_AFU processing The resolution to this problem is to have the reset handler drain all outstanding user space initiated ioctls before proceeding. It is safe to drain after the state has been changed to STATE_RESET. Also since drain_ioctls() was static, it had to be moved up a bit to be before cxlflash_eh_host_reset_handler(). Signed-off-by: Manoj N. Kumar <manoj@linux.vnet.ibm.com> Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
2a81ffdd9d
commit
f411396d94
@ -1915,6 +1915,19 @@ static int afu_reset(struct cxlflash_cfg *cfg)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* drain_ioctls() - wait until all currently executing ioctls have completed
|
||||
* @cfg: Internal structure associated with the host.
|
||||
*
|
||||
* Obtain write access to read/write semaphore that wraps ioctl
|
||||
* handling to 'drain' ioctls currently executing.
|
||||
*/
|
||||
static void drain_ioctls(struct cxlflash_cfg *cfg)
|
||||
{
|
||||
down_write(&cfg->ioctl_rwsem);
|
||||
up_write(&cfg->ioctl_rwsem);
|
||||
}
|
||||
|
||||
/**
|
||||
* cxlflash_eh_device_reset_handler() - reset a single LUN
|
||||
* @scp: SCSI command to send.
|
||||
@ -1986,6 +1999,7 @@ static int cxlflash_eh_host_reset_handler(struct scsi_cmnd *scp)
|
||||
switch (cfg->state) {
|
||||
case STATE_NORMAL:
|
||||
cfg->state = STATE_RESET;
|
||||
drain_ioctls(cfg);
|
||||
cxlflash_mark_contexts_error(cfg);
|
||||
rcr = afu_reset(cfg);
|
||||
if (rcr) {
|
||||
@ -2503,19 +2517,6 @@ out_remove:
|
||||
goto out;
|
||||
}
|
||||
|
||||
/**
|
||||
* drain_ioctls() - wait until all currently executing ioctls have completed
|
||||
* @cfg: Internal structure associated with the host.
|
||||
*
|
||||
* Obtain write access to read/write semaphore that wraps ioctl
|
||||
* handling to 'drain' ioctls currently executing.
|
||||
*/
|
||||
static void drain_ioctls(struct cxlflash_cfg *cfg)
|
||||
{
|
||||
down_write(&cfg->ioctl_rwsem);
|
||||
up_write(&cfg->ioctl_rwsem);
|
||||
}
|
||||
|
||||
/**
|
||||
* cxlflash_pci_error_detected() - called when a PCI error is detected
|
||||
* @pdev: PCI device struct.
|
||||
|
Loading…
Reference in New Issue
Block a user