Skip to content

Commit

Permalink
megaraid_sas : Update threshold based reply post host index register
Browse files Browse the repository at this point in the history
Resending the patch. Addressed the review comments from Tomas Henzl.

Current driver updates reply post host index to let firmware know that replies are processed,
while returning from ISR function, only if there is no oustanding replies in reply queue.

Driver will free the request frame immediately from ISR but reply post host index is not yet updated.
It means freed request can be used by submission path and there may be a tight loop in request/reply
path. In such condition, firmware may crash when it tries to post reply and there is no free
reply post descriptor.

Eventually two things needs to be change to avoid this issue.

Increase reply queue depth (double than request queue) to accommodate worst case scenario.
Update reply post host index to firmware once it reach to some pre-defined threshold value.

This change will make sure that firmware will always have some buffer of reply descriptor and
will never find empty reply descriptor in completion path.

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 0756040 commit db4fc86
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
23 changes: 22 additions & 1 deletion drivers/scsi/megaraid/megaraid_sas_fusion.c
Original file line number Diff line number Diff line change
Expand Up @@ -971,7 +971,7 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)

max_cmd = instance->max_fw_cmds;

fusion->reply_q_depth = ((max_cmd + 1 + 15)/16)*16;
fusion->reply_q_depth = 2 * (((max_cmd + 1 + 15)/16)*16);

fusion->request_alloc_sz =
sizeof(union MEGASAS_REQUEST_DESCRIPTOR_UNION) *max_cmd;
Expand Down Expand Up @@ -1874,6 +1874,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
u32 status, extStatus, device_id;
union desc_value d_val;
struct LD_LOAD_BALANCE_INFO *lbinfo;
int threshold_reply_count = 0;

fusion = instance->ctrl_context;

Expand Down Expand Up @@ -1961,6 +1962,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)

desc->Words = ULLONG_MAX;
num_completed++;
threshold_reply_count++;

/* Get the next reply descriptor */
if (!fusion->last_reply_idx[MSIxIndex])
Expand All @@ -1980,6 +1982,25 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)

if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
break;
/*
* Write to reply post host index register after completing threshold
* number of reply counts and still there are more replies in reply queue
* pending to be completed
*/
if (threshold_reply_count >= THRESHOLD_REPLY_COUNT) {
if ((instance->pdev->device ==
PCI_DEVICE_ID_LSI_INVADER) ||
(instance->pdev->device ==
PCI_DEVICE_ID_LSI_FURY))
writel(((MSIxIndex & 0x7) << 24) |
fusion->last_reply_idx[MSIxIndex],
instance->reply_post_host_index_addr[MSIxIndex/8]);
else
writel((MSIxIndex << 24) |
fusion->last_reply_idx[MSIxIndex],
instance->reply_post_host_index_addr[0]);
threshold_reply_count = 0;
}
}

if (!num_completed)
Expand Down
1 change: 1 addition & 0 deletions drivers/scsi/megaraid/megaraid_sas_fusion.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE {

#define MEGASAS_FP_CMD_LEN 16
#define MEGASAS_FUSION_IN_RESET 0
#define THRESHOLD_REPLY_COUNT 50

/*
* Raid Context structure which describes MegaRAID specific IO Parameters
Expand Down

0 comments on commit db4fc86

Please sign in to comment.