Skip to content

Commit

Permalink
scsi: cxlflash: Support multiple hardware queues
Browse files Browse the repository at this point in the history
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: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Uma Krishnan authored and Martin K. Petersen committed Apr 14, 2017
1 parent e2ef33f commit bfc0bab
Show file tree
Hide file tree
Showing 3 changed files with 309 additions and 164 deletions.
41 changes: 29 additions & 12 deletions drivers/scsi/cxlflash/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -164,25 +167,21 @@ 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 */

/* 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;
Expand All @@ -194,21 +193,39 @@ 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 */

char version[16];
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;
Expand Down
Loading

0 comments on commit bfc0bab

Please sign in to comment.