Commit afd3a579 authored by Sreekanth Reddy's avatar Sreekanth Reddy Committed by Martin K. Petersen

scsi: mpi3mr: Add io_uring interface support in I/O-polled mode

Add support for the io_uring interface in I/O-polled mode.

This feature is disabled in the driver by default. To enable the feature, a
module parameter "poll_queues" has to be set with the desired number of
polling queues.

When the feature is enabled, the driver reserves a certain number of
operational queue pairs for the poll_queues either from the available queue
pairs or creates additional queue pairs based on the operational queue
availability.

The Polling queues will have corresponding IRQ and ISR functions as similar
to default queues. However, the IRQ line is disabled by the driver for
poll_queues.

Link: https://lore.kernel.org/r/20211220141159.16117-22-sreekanth.reddy@broadcom.comSigned-off-by: default avatarSreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 95cca8d5
......@@ -220,6 +220,12 @@ enum mpi3mr_reset_reason {
MPI3MR_RESET_FROM_FIRMWARE = 27,
};
/* Queue type definitions */
enum queue_type {
MPI3MR_DEFAULT_QUEUE = 0,
MPI3MR_POLL_QUEUE,
};
/**
* struct mpi3mr_compimg_ver - replica of component image
* version defined in mpi30_image.h in host endianness
......@@ -331,6 +337,7 @@ struct op_req_qinfo {
* @pend_ios: Number of IOs pending in HW for this queue
* @enable_irq_poll: Flag to indicate polling is enabled
* @in_use: Queue is handled by poll/ISR
* @qtype: Type of queue (types defined in enum queue_type)
*/
struct op_reply_qinfo {
u16 ci;
......@@ -345,6 +352,7 @@ struct op_reply_qinfo {
atomic_t pend_ios;
bool enable_irq_poll;
atomic_t in_use;
enum queue_type qtype;
};
/**
......@@ -703,6 +711,9 @@ struct scmd_priv {
* @driver_info: Driver, Kernel, OS information to firmware
* @change_count: Topology change count
* @op_reply_q_offset: Operational reply queue offset with MSIx
* @default_qcount: Total Default queues
* @active_poll_qcount: Currently active poll queue count
* @requested_poll_qcount: User requested poll queue count
*/
struct mpi3mr_ioc {
struct list_head list;
......@@ -839,6 +850,10 @@ struct mpi3mr_ioc {
struct mpi3_driver_info_layout driver_info;
u16 change_count;
u16 op_reply_q_offset;
u16 default_qcount;
u16 active_poll_qcount;
u16 requested_poll_qcount;
};
/**
......@@ -940,5 +955,8 @@ void mpi3mr_flush_delayed_cmd_lists(struct mpi3mr_ioc *mrioc);
void mpi3mr_check_rh_fault_ioc(struct mpi3mr_ioc *mrioc, u32 reason_code);
void mpi3mr_print_fault_info(struct mpi3mr_ioc *mrioc);
void mpi3mr_check_rh_fault_ioc(struct mpi3mr_ioc *mrioc, u32 reason_code);
int mpi3mr_process_op_reply_q(struct mpi3mr_ioc *mrioc,
struct op_reply_qinfo *op_reply_q);
int mpi3mr_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num);
#endif /*MPI3MR_H_INCLUDED*/
This diff is collapsed.
......@@ -3049,17 +3049,49 @@ static int mpi3mr_bios_param(struct scsi_device *sdev,
* mpi3mr_map_queues - Map queues callback handler
* @shost: SCSI host reference
*
* Call the blk_mq_pci_map_queues with from which operational
* queue the mapping has to be done
* Maps default and poll queues.
*
* Return: return of blk_mq_pci_map_queues
* Return: return zero.
*/
static int mpi3mr_map_queues(struct Scsi_Host *shost)
{
struct mpi3mr_ioc *mrioc = shost_priv(shost);
int i, qoff, offset;
struct blk_mq_queue_map *map = NULL;
offset = mrioc->op_reply_q_offset;
for (i = 0, qoff = 0; i < HCTX_MAX_TYPES; i++) {
map = &shost->tag_set.map[i];
map->nr_queues = 0;
if (i == HCTX_TYPE_DEFAULT)
map->nr_queues = mrioc->default_qcount;
else if (i == HCTX_TYPE_POLL)
map->nr_queues = mrioc->active_poll_qcount;
if (!map->nr_queues) {
BUG_ON(i == HCTX_TYPE_DEFAULT);
continue;
}
/*
* The poll queue(s) doesn't have an IRQ (and hence IRQ
* affinity), so use the regular blk-mq cpu mapping
*/
map->queue_offset = qoff;
if (i != HCTX_TYPE_POLL)
blk_mq_pci_map_queues(map, mrioc->pdev, offset);
else
blk_mq_map_queues(map);
qoff += map->nr_queues;
offset += map->nr_queues;
}
return 0;
return blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT],
mrioc->pdev, mrioc->op_reply_q_offset);
}
/**
......@@ -3873,6 +3905,7 @@ static struct scsi_host_template mpi3mr_driver_template = {
.eh_host_reset_handler = mpi3mr_eh_host_reset,
.bios_param = mpi3mr_bios_param,
.map_queues = mpi3mr_map_queues,
.mq_poll = mpi3mr_blk_mq_poll,
.no_write_same = 1,
.can_queue = 1,
.this_id = -1,
......@@ -4105,6 +4138,9 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
shost->nr_hw_queues = mrioc->num_op_reply_q;
if (mrioc->active_poll_qcount)
shost->nr_maps = 3;
shost->can_queue = mrioc->max_host_ios;
shost->sg_tablesize = MPI3MR_SG_DEPTH;
shost->max_id = mrioc->facts.max_perids + 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment