Skip to content

Commit

Permalink
megaraid_sas : MFI MPT linked list corruption fix
Browse files Browse the repository at this point in the history
Resending the patch. Addressed the review comments from Tomas Henzl.
Added comment for to-do work.

Problem statement:
MFI link list in megaraid_sas driver is used from mfi-mpt pass-through commands.
This list can be corrupted due to many possible race conditions in driver and
eventually we may see kernel panic.

One example -
MFI frame is freed from calling process as driver send command via polling method and interrupt
for that command comes after driver free mfi frame (actually even after some other context reuse
the mfi frame). When driver receive MPT frame in ISR, driver will be using the index of MFI and
access that MFI frame and finally in-used MFI frame’s list will be corrupted.

High level description of new solution -
Free MFI and MPT command from same context.
Free both the command either from process (from where mfi-mpt pass-through was called) or from
ISR context. Do not split freeing of MFI and MPT, because it creates the race condition which
will do MFI/MPT list corruption.

Renamed the cmd_pool_lock which is used in instance as well as fusion with below name.
mfi_pool_lock and mpt_pool_lock to add more code readability.

Signed-off-by: Sumit Saxena <sumit.saxena@avagotech.com>
Signed-off-by: Kashyap Desai <kashyap.desai@avagotech.com>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
  • Loading branch information
Sumit.Saxena@avagotech.com authored and Christoph Hellwig committed Sep 16, 2014
1 parent d2552eb commit 90dc9d9
Show file tree
Hide file tree
Showing 4 changed files with 241 additions and 83 deletions.
25 changes: 23 additions & 2 deletions drivers/scsi/megaraid/megaraid_sas.h
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,12 @@ struct megasas_ctrl_info {

#define VD_EXT_DEBUG 0

enum MR_MFI_MPT_PTHR_FLAGS {
MFI_MPT_DETACHED = 0,
MFI_LIST_ADDED = 1,
MFI_MPT_ATTACHED = 2,
};

/* Frame Type */
#define IO_FRAME 0
#define PTHRU_FRAME 1
Expand All @@ -1033,7 +1039,7 @@ struct megasas_ctrl_info {
#define MEGASAS_IOCTL_CMD 0
#define MEGASAS_DEFAULT_CMD_TIMEOUT 90
#define MEGASAS_THROTTLE_QUEUE_DEPTH 16

#define MEGASAS_BLOCKED_CMD_TIMEOUT 60
/*
* FW reports the maximum of number of commands that it can accept (maximum
* commands that can be outstanding) at any time. The driver must report a
Expand Down Expand Up @@ -1652,7 +1658,7 @@ struct megasas_instance {
struct megasas_cmd **cmd_list;
struct list_head cmd_pool;
/* used to sync fire the cmd to fw */
spinlock_t cmd_pool_lock;
spinlock_t mfi_pool_lock;
/* used to sync fire the cmd to fw */
spinlock_t hba_lock;
/* used to synch producer, consumer ptrs in dpc */
Expand Down Expand Up @@ -1839,6 +1845,11 @@ struct megasas_cmd {

struct list_head list;
struct scsi_cmnd *scmd;

void *mpt_pthr_cmd_blocked;
atomic_t mfi_mpt_pthr;
u8 is_wait_event;

struct megasas_instance *instance;
union {
struct {
Expand Down Expand Up @@ -1927,4 +1938,14 @@ int megasas_set_crash_dump_params(struct megasas_instance *instance,
void megasas_free_host_crash_buffer(struct megasas_instance *instance);
void megasas_fusion_crash_dump_wq(struct work_struct *work);

void megasas_return_cmd_fusion(struct megasas_instance *instance,
struct megasas_cmd_fusion *cmd);
int megasas_issue_blocked_cmd(struct megasas_instance *instance,
struct megasas_cmd *cmd, int timeout);
void __megasas_return_cmd(struct megasas_instance *instance,
struct megasas_cmd *cmd);

void megasas_return_mfi_mpt_pthr(struct megasas_instance *instance,
struct megasas_cmd *cmd_mfi, struct megasas_cmd_fusion *cmd_fusion);

#endif /*LSI_MEGARAID_SAS_H */
Loading

0 comments on commit 90dc9d9

Please sign in to comment.