mirror of https://gitee.com/openkylin/linux.git
[SCSI] sym2: Fix build when spinlock debugging is enabled
When spinlock debugging is turned on, a struct completion grows beyond the size allowed for the scsi_pointer. So move the struct completion back onto the stack. The additional memory barriers are to keep us from completing a random piece of kernel stack if the command happens to complete after the error handling has finished. Signed-off-by: Matthew Wilcox <matthew@wil.cx> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
80286d478c
commit
d637c4543f
|
@ -140,11 +140,11 @@ static struct scsi_transport_template *sym2_transport_template = NULL;
|
||||||
* Driver private area in the SCSI command structure.
|
* Driver private area in the SCSI command structure.
|
||||||
*/
|
*/
|
||||||
struct sym_ucmd { /* Override the SCSI pointer structure */
|
struct sym_ucmd { /* Override the SCSI pointer structure */
|
||||||
struct completion done;
|
dma_addr_t data_mapping;
|
||||||
void (*old_done)(struct scsi_cmnd *);
|
unsigned char data_mapped;
|
||||||
dma_addr_t data_mapping;
|
unsigned char to_do; /* For error handling */
|
||||||
int to_do;
|
void (*old_done)(struct scsi_cmnd *); /* For error handling */
|
||||||
u_char data_mapped; /* corresponds to data_mapping above */
|
struct completion *eh_done; /* For error handling */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SYM_UCMD_PTR(cmd) ((struct sym_ucmd *)(&(cmd)->SCp))
|
#define SYM_UCMD_PTR(cmd) ((struct sym_ucmd *)(&(cmd)->SCp))
|
||||||
|
@ -713,7 +713,7 @@ static void sym_eh_done(struct scsi_cmnd *cmd)
|
||||||
cmd->scsi_done = ucmd->old_done;
|
cmd->scsi_done = ucmd->old_done;
|
||||||
|
|
||||||
if (ucmd->to_do == SYM_EH_DO_WAIT)
|
if (ucmd->to_do == SYM_EH_DO_WAIT)
|
||||||
complete(&ucmd->done);
|
complete(ucmd->eh_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -728,6 +728,7 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
|
||||||
SYM_QUEHEAD *qp;
|
SYM_QUEHEAD *qp;
|
||||||
int to_do = SYM_EH_DO_IGNORE;
|
int to_do = SYM_EH_DO_IGNORE;
|
||||||
int sts = -1;
|
int sts = -1;
|
||||||
|
struct completion eh_done;
|
||||||
|
|
||||||
dev_warn(&cmd->device->sdev_gendev, "%s operation started.\n", opname);
|
dev_warn(&cmd->device->sdev_gendev, "%s operation started.\n", opname);
|
||||||
|
|
||||||
|
@ -742,8 +743,10 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to_do == SYM_EH_DO_WAIT) {
|
if (to_do == SYM_EH_DO_WAIT) {
|
||||||
init_completion(&ucmd->done);
|
init_completion(&eh_done);
|
||||||
ucmd->old_done = cmd->scsi_done;
|
ucmd->old_done = cmd->scsi_done;
|
||||||
|
ucmd->eh_done = &eh_done;
|
||||||
|
wmb();
|
||||||
cmd->scsi_done = sym_eh_done;
|
cmd->scsi_done = sym_eh_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -779,8 +782,9 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
|
||||||
spin_unlock_irq(host->host_lock);
|
spin_unlock_irq(host->host_lock);
|
||||||
|
|
||||||
if (to_do == SYM_EH_DO_WAIT) {
|
if (to_do == SYM_EH_DO_WAIT) {
|
||||||
if (!wait_for_completion_timeout(&ucmd->done, 5*HZ)) {
|
if (!wait_for_completion_timeout(&eh_done, 5*HZ)) {
|
||||||
ucmd->to_do = SYM_EH_DO_IGNORE;
|
ucmd->to_do = SYM_EH_DO_IGNORE;
|
||||||
|
wmb();
|
||||||
sts = -2;
|
sts = -2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue