提交 bfc0bab1 编写于 作者: U Uma Krishnan 提交者: Martin K. Petersen

scsi: cxlflash: Support multiple hardware queues

Introduce multiple hardware queues to improve legacy I/O path performance.
Each hardware queue is comprised of a master context and associated I/O
resources. The hardware queues are initially implemented as a static array
embedded in the AFU. This will be transitioned to a dynamic allocation in a
later series to improve the memory footprint of the driver.
Signed-off-by: NUma Krishnan <ukrishn@linux.vnet.ibm.com>
Acked-by: NMatthew R. Ochs <mrochs@linux.vnet.ibm.com>
Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
上级 e2ef33fa
......@@ -60,6 +60,9 @@ extern const struct file_operations cxlflash_cxl_fops;
/* SQ for master issued cmds */
#define NUM_SQ_ENTRY CXLFLASH_MAX_CMDS
#define CXLFLASH_NUM_HWQS 1
#define PRIMARY_HWQ 0
static inline void check_sizes(void)
{
......@@ -98,7 +101,6 @@ enum cxlflash_state {
struct cxlflash_cfg {
struct afu *afu;
struct cxl_context *mcctx;
struct pci_dev *dev;
struct pci_device_id *dev_id;
......@@ -144,6 +146,7 @@ struct afu_cmd {
struct list_head queue;
u8 cmd_tmf:1;
u32 hwq_index;
/* As per the SISLITE spec the IOARCB EA has to be 16-byte aligned.
* However for performance reasons the IOARCB/IOASA should be
......@@ -164,7 +167,7 @@ static inline struct afu_cmd *sc_to_afucz(struct scsi_cmnd *sc)
return afuc;
}
struct afu {
struct hwq {
/* Stuff requiring alignment go first. */
struct sisl_ioarcb sq[NUM_SQ_ENTRY]; /* 16K SQ */
u64 rrq_entry[NUM_RRQ_ENTRY]; /* 2K RRQ */
......@@ -172,17 +175,13 @@ struct afu {
/* Beware of alignment till here. Preferably introduce new
* fields after this point
*/
int (*send_cmd)(struct afu *, struct afu_cmd *);
void (*context_reset)(struct afu_cmd *);
/* AFU HW */
struct afu *afu;
struct cxl_context *ctx;
struct cxl_ioctl_start_work work;
struct cxlflash_afu_map __iomem *afu_map; /* entire MMIO map */
struct sisl_host_map __iomem *host_map; /* MC host map */
struct sisl_ctrl_map __iomem *ctrl_map; /* MC control map */
ctx_hndl_t ctx_hndl; /* master's context handle */
u32 index; /* Index of this hwq */
atomic_t hsq_credits;
spinlock_t hsq_slock;
......@@ -194,9 +193,22 @@ struct afu {
u64 *hrrq_end;
u64 *hrrq_curr;
bool toggle;
atomic_t cmds_active; /* Number of currently active AFU commands */
s64 room;
spinlock_t rrin_slock; /* Lock to rrin queuing and cmd_room updates */
struct irq_poll irqpoll;
} __aligned(cache_line_size());
struct afu {
struct hwq hwqs[CXLFLASH_NUM_HWQS];
int (*send_cmd)(struct afu *, struct afu_cmd *);
void (*context_reset)(struct afu_cmd *);
/* AFU HW */
struct cxlflash_afu_map __iomem *afu_map; /* entire MMIO map */
atomic_t cmds_active; /* Number of currently active AFU commands */
u64 hb;
u32 internal_lun; /* User-desired LUN mode for this AFU */
......@@ -204,11 +216,16 @@ struct afu {
u64 interface_version;
u32 irqpoll_weight;
struct irq_poll irqpoll;
struct cxlflash_cfg *parent; /* Pointer back to parent cxlflash_cfg */
};
static inline struct hwq *get_hwq(struct afu *afu, u32 index)
{
WARN_ON(index >= CXLFLASH_NUM_HWQS);
return &afu->hwqs[index];
}
static inline bool afu_is_irqpoll_enabled(struct afu *afu)
{
return !!afu->irqpoll_weight;
......
此差异已折叠。
......@@ -254,6 +254,7 @@ static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi)
struct afu *afu = cfg->afu;
struct sisl_ctrl_map __iomem *ctrl_map = ctxi->ctrl_map;
int rc = 0;
struct hwq *hwq = get_hwq(afu, PRIMARY_HWQ);
u64 val;
/* Unlock cap and restrict user to read/write cmds in translated mode */
......@@ -270,7 +271,7 @@ static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi)
/* Set up MMIO registers pointing to the RHT */
writeq_be((u64)ctxi->rht_start, &ctrl_map->rht_start);
val = SISL_RHT_CNT_ID((u64)MAX_RHT_PER_CONTEXT, (u64)(afu->ctx_hndl));
val = SISL_RHT_CNT_ID((u64)MAX_RHT_PER_CONTEXT, (u64)(hwq->ctx_hndl));
writeq_be(val, &ctrl_map->rht_cnt_id);
out:
dev_dbg(dev, "%s: returning rc=%d\n", __func__, rc);
......@@ -1626,6 +1627,7 @@ static int cxlflash_afu_recover(struct scsi_device *sdev,
struct afu *afu = cfg->afu;
struct ctx_info *ctxi = NULL;
struct mutex *mutex = &cfg->ctx_recovery_mutex;
struct hwq *hwq = get_hwq(afu, PRIMARY_HWQ);
u64 flags;
u64 ctxid = DECODE_CTXID(recover->context_id),
rctxid = recover->context_id;
......@@ -1696,7 +1698,7 @@ static int cxlflash_afu_recover(struct scsi_device *sdev,
}
/* Test if in error state */
reg = readq_be(&afu->ctrl_map->mbox_r);
reg = readq_be(&hwq->ctrl_map->mbox_r);
if (reg == -1) {
dev_dbg(dev, "%s: MMIO fail, wait for recovery.\n", __func__);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册