未验证 提交 6981ca3c 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!426 scsi:sssraid: Introduce map_queue in sssraid module & code quality reinforcement content

Merge Pull Request from: @steven-song3 
 
Introduce map_queue in sssraid module for performance enhancement.

Quality reinforcement content:

1. use bsg_remove_queue replace sssraid_remove_bsg to
address insufficient resource release.
2. set pdev private data to NULL when probe process
failed to prevent accessing null pointers in next
possible exit process.
3. modifications for code review recommendations. 
 
Link:https://gitee.com/openeuler/kernel/pulls/426 

Reviewed-by: Zheng Zengkai <zhengzengkai@huawei.com> 
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com> 
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#define SSSRAID_DRIVER_NAME "sssraid" #define SSSRAID_DRIVER_NAME "sssraid"
#define SSSRAID_NAME_LENGTH 32 #define SSSRAID_NAME_LENGTH 32
#define BSG_NAME_SIZE 15
/* /*
* SSSRAID Vendor ID and Device IDs * SSSRAID Vendor ID and Device IDs
*/ */
...@@ -92,6 +92,13 @@ extern u32 admin_tmout; ...@@ -92,6 +92,13 @@ extern u32 admin_tmout;
#define SSSRAID_DMA_MSK_BIT_MAX 64 #define SSSRAID_DMA_MSK_BIT_MAX 64
enum {
SCSI_6_BYTE_CDB_LEN = 6,
SCSI_10_BYTE_CDB_LEN = 10,
SCSI_12_BYTE_CDB_LEN = 12,
SCSI_16_BYTE_CDB_LEN = 16,
};
enum { enum {
SSSRAID_SGL_FMT_DATA_DESC = 0x00, SSSRAID_SGL_FMT_DATA_DESC = 0x00,
SSSRAID_SGL_FMT_SEG_DESC = 0x02, SSSRAID_SGL_FMT_SEG_DESC = 0x02,
......
...@@ -188,14 +188,18 @@ static int sssraid_alloc_resources(struct sssraid_ioc *sdioc) ...@@ -188,14 +188,18 @@ static int sssraid_alloc_resources(struct sssraid_ioc *sdioc)
return -ENOMEM; return -ENOMEM;
retval = sssraid_create_dma_pools(sdioc); retval = sssraid_create_dma_pools(sdioc);
if (retval) if (retval) {
ioc_err(sdioc, "err: failure at create dma pool!\n");
goto free_ctrl_info; goto free_ctrl_info;
}
/* not num_online_cpus */ /* not num_online_cpus */
nqueue = num_possible_cpus() + 1; nqueue = num_possible_cpus() + 1;
sdioc->cqinfo = kcalloc_node(nqueue, sizeof(struct sssraid_cqueue), sdioc->cqinfo = kcalloc_node(nqueue, sizeof(struct sssraid_cqueue),
GFP_KERNEL, sdioc->numa_node); GFP_KERNEL, sdioc->numa_node);
if (!sdioc->cqinfo) { if (!sdioc->cqinfo) {
retval = -ENOMEM; retval = -ENOMEM;
ioc_err(sdioc, "err: failure at alloc memory for cqueue!");
goto destroy_dma_pools; goto destroy_dma_pools;
} }
...@@ -203,6 +207,7 @@ static int sssraid_alloc_resources(struct sssraid_ioc *sdioc) ...@@ -203,6 +207,7 @@ static int sssraid_alloc_resources(struct sssraid_ioc *sdioc)
GFP_KERNEL, sdioc->numa_node); GFP_KERNEL, sdioc->numa_node);
if (!sdioc->sqinfo) { if (!sdioc->sqinfo) {
retval = -ENOMEM; retval = -ENOMEM;
ioc_err(sdioc, "err: failure at alloc memory for squeue!");
goto free_cqueues; goto free_cqueues;
} }
...@@ -263,7 +268,7 @@ static int sssraid_setup_resources(struct sssraid_ioc *sdioc) ...@@ -263,7 +268,7 @@ static int sssraid_setup_resources(struct sssraid_ioc *sdioc)
*/ */
retval = sssraid_remap_bar(sdioc, SSSRAID_REG_DBS + 4096); retval = sssraid_remap_bar(sdioc, SSSRAID_REG_DBS + 4096);
if (retval) { if (retval) {
retval = -ENODEV; ioc_err(sdioc, "Failed to re-map bar, error %d\n", retval);
goto out_failed; goto out_failed;
} }
...@@ -282,7 +287,7 @@ static int sssraid_setup_resources(struct sssraid_ioc *sdioc) ...@@ -282,7 +287,7 @@ static int sssraid_setup_resources(struct sssraid_ioc *sdioc)
maskbit = SSSRAID_CAP_DMAMASK(sdioc->cap); maskbit = SSSRAID_CAP_DMAMASK(sdioc->cap);
if (maskbit < 32 || maskbit > SSSRAID_DMA_MSK_BIT_MAX) { if (maskbit < 32 || maskbit > SSSRAID_DMA_MSK_BIT_MAX) {
ioc_err(sdioc, "err: DMA MASK BIT invalid[%llu], set to default\n", maskbit); ioc_notice(sdioc, "err: DMA MASK BIT invalid[%llu], set to default\n", maskbit);
maskbit = SSSRAID_DMA_MSK_BIT_MAX; maskbit = SSSRAID_DMA_MSK_BIT_MAX;
} }
...@@ -352,13 +357,16 @@ static int sssraid_alloc_qpair(struct sssraid_ioc *sdioc, u16 qidx, u16 depth) ...@@ -352,13 +357,16 @@ static int sssraid_alloc_qpair(struct sssraid_ioc *sdioc, u16 qidx, u16 depth)
cqinfo->cqes = dma_alloc_coherent(&sdioc->pdev->dev, CQ_SIZE(depth), cqinfo->cqes = dma_alloc_coherent(&sdioc->pdev->dev, CQ_SIZE(depth),
&cqinfo->cq_dma_addr, GFP_KERNEL | __GFP_ZERO); &cqinfo->cq_dma_addr, GFP_KERNEL | __GFP_ZERO);
if (!cqinfo->cqes) if (!cqinfo->cqes) {
ioc_err(sdioc, "failure at alloc dma space for cqueue.\n");
return -ENOMEM; return -ENOMEM;
}
sqinfo->sq_cmds = dma_alloc_coherent(&sdioc->pdev->dev, SQ_SIZE(qidx, depth), sqinfo->sq_cmds = dma_alloc_coherent(&sdioc->pdev->dev, SQ_SIZE(qidx, depth),
&sqinfo->sq_dma_addr, GFP_KERNEL); &sqinfo->sq_dma_addr, GFP_KERNEL);
if (!sqinfo->sq_cmds) { if (!sqinfo->sq_cmds) {
retval = -ENOMEM; retval = -ENOMEM;
ioc_err(sdioc, "failure at alloc dma space for squeue cmds.\n");
goto free_cqes; goto free_cqes;
} }
...@@ -367,6 +375,7 @@ static int sssraid_alloc_qpair(struct sssraid_ioc *sdioc, u16 qidx, u16 depth) ...@@ -367,6 +375,7 @@ static int sssraid_alloc_qpair(struct sssraid_ioc *sdioc, u16 qidx, u16 depth)
&sqinfo->sense_dma_addr, GFP_KERNEL | __GFP_ZERO); &sqinfo->sense_dma_addr, GFP_KERNEL | __GFP_ZERO);
if (!sqinfo->sense) { if (!sqinfo->sense) {
retval = -ENOMEM; retval = -ENOMEM;
ioc_err(sdioc, "failure at alloc dma space for sense data.\n");
goto free_sq_cmds; goto free_sq_cmds;
} }
...@@ -420,8 +429,10 @@ static int sssraid_setup_admin_qpair(struct sssraid_ioc *sdioc) ...@@ -420,8 +429,10 @@ static int sssraid_setup_admin_qpair(struct sssraid_ioc *sdioc)
ioc_info(sdioc, "Starting disable ctrl...\n"); ioc_info(sdioc, "Starting disable ctrl...\n");
retval = sssraid_disable_ctrl(sdioc); retval = sssraid_disable_ctrl(sdioc);
if (retval) if (retval) {
ioc_err(sdioc, "disable ctrl failed\n");
return retval; return retval;
}
/* this func don't alloc admin queue */ /* this func don't alloc admin queue */
...@@ -435,6 +446,7 @@ static int sssraid_setup_admin_qpair(struct sssraid_ioc *sdioc) ...@@ -435,6 +446,7 @@ static int sssraid_setup_admin_qpair(struct sssraid_ioc *sdioc)
retval = sssraid_enable_ctrl(sdioc); retval = sssraid_enable_ctrl(sdioc);
if (retval) { if (retval) {
ioc_err(sdioc, "enable ctrl failed\n");
retval = -ENODEV; retval = -ENODEV;
return retval; return retval;
} }
...@@ -633,7 +645,7 @@ static int sssraid_setup_isr(struct sssraid_ioc *sdioc, u8 setup_one) ...@@ -633,7 +645,7 @@ static int sssraid_setup_isr(struct sssraid_ioc *sdioc, u8 setup_one)
goto out_failed; goto out_failed;
} }
if (i != max_vectors) { if (i != max_vectors) {
ioc_info(sdioc, ioc_warn(sdioc,
"Allocated vectors (%d) are less than requested (%d)\n", "Allocated vectors (%d) are less than requested (%d)\n",
i, max_vectors); i, max_vectors);
...@@ -643,7 +655,8 @@ static int sssraid_setup_isr(struct sssraid_ioc *sdioc, u8 setup_one) ...@@ -643,7 +655,8 @@ static int sssraid_setup_isr(struct sssraid_ioc *sdioc, u8 setup_one)
sdioc->intr_info = kzalloc(sizeof(struct sssraid_intr_info) * max_vectors, sdioc->intr_info = kzalloc(sizeof(struct sssraid_intr_info) * max_vectors,
GFP_KERNEL); GFP_KERNEL);
if (!sdioc->intr_info) { if (!sdioc->intr_info) {
retval = -1; retval = -ENOMEM;
ioc_err(sdioc, "err: failed to alloc memory for intr_info!\n");
pci_free_irq_vectors(sdioc->pdev); pci_free_irq_vectors(sdioc->pdev);
goto out_failed; goto out_failed;
} }
...@@ -651,6 +664,7 @@ static int sssraid_setup_isr(struct sssraid_ioc *sdioc, u8 setup_one) ...@@ -651,6 +664,7 @@ static int sssraid_setup_isr(struct sssraid_ioc *sdioc, u8 setup_one)
for (i = 0; i < max_vectors; i++) { for (i = 0; i < max_vectors; i++) {
retval = sssraid_request_irq(sdioc, i); retval = sssraid_request_irq(sdioc, i);
if (retval) { if (retval) {
ioc_err(sdioc, "err: request irq for pci device failed.\n");
sdioc->intr_info_count = i; /* =i is for offload interrupt loop counter */ sdioc->intr_info_count = i; /* =i is for offload interrupt loop counter */
goto out_failed; goto out_failed;
} }
...@@ -1174,14 +1188,16 @@ static inline void sssraid_send_all_aen(struct sssraid_ioc *sdioc) ...@@ -1174,14 +1188,16 @@ static inline void sssraid_send_all_aen(struct sssraid_ioc *sdioc)
sssraid_send_event_ack(sdioc, 0, 0, i + SSSRAID_AMDQ_BLK_MQ_DEPTH); sssraid_send_event_ack(sdioc, 0, 0, i + SSSRAID_AMDQ_BLK_MQ_DEPTH);
} }
static int sssraid_dev_list_init(struct sssraid_ioc *sdioc) static int sssraid_disk_list_init(struct sssraid_ioc *sdioc)
{ {
u32 nd = le32_to_cpu(sdioc->ctrl_info->nd); u32 nd = le32_to_cpu(sdioc->ctrl_info->nd);
sdioc->devices = kzalloc_node(nd * sizeof(struct sssraid_dev_info), sdioc->devices = kzalloc_node(nd * sizeof(struct sssraid_dev_info),
GFP_KERNEL, sdioc->numa_node); GFP_KERNEL, sdioc->numa_node);
if (!sdioc->devices) if (!sdioc->devices) {
ioc_err(sdioc, "err: failed to alloc memory for device info.\n");
return -ENOMEM; return -ENOMEM;
}
return 0; return 0;
} }
...@@ -1331,7 +1347,7 @@ int sssraid_init_ioc(struct sssraid_ioc *sdioc, u8 re_init) ...@@ -1331,7 +1347,7 @@ int sssraid_init_ioc(struct sssraid_ioc *sdioc, u8 re_init)
sssraid_send_all_aen(sdioc); sssraid_send_all_aen(sdioc);
if (!re_init) { if (!re_init) {
retval = sssraid_dev_list_init(sdioc); retval = sssraid_disk_list_init(sdioc);
if (retval) { if (retval) {
ioc_err(sdioc, "Failed to init device list, error %d\n", ioc_err(sdioc, "Failed to init device list, error %d\n",
retval); retval);
...@@ -1358,6 +1374,7 @@ void sssraid_cleanup_resources(struct sssraid_ioc *sdioc) ...@@ -1358,6 +1374,7 @@ void sssraid_cleanup_resources(struct sssraid_ioc *sdioc)
{ {
struct pci_dev *pdev = sdioc->pdev; struct pci_dev *pdev = sdioc->pdev;
pci_set_drvdata(pdev, NULL);
sssraid_cleanup_isr(sdioc); sssraid_cleanup_isr(sdioc);
if (sdioc->bar) { if (sdioc->bar) {
...@@ -1372,6 +1389,12 @@ void sssraid_cleanup_resources(struct sssraid_ioc *sdioc) ...@@ -1372,6 +1389,12 @@ void sssraid_cleanup_resources(struct sssraid_ioc *sdioc)
} }
} }
static void sssraid_free_disk_list(struct sssraid_ioc *sdioc)
{
kfree(sdioc->devices);
sdioc->devices = NULL;
}
static void sssraid_free_ioq_ptcmds(struct sssraid_ioc *sdioc) static void sssraid_free_ioq_ptcmds(struct sssraid_ioc *sdioc)
{ {
kfree(sdioc->ioq_ptcmds); kfree(sdioc->ioq_ptcmds);
...@@ -1382,7 +1405,7 @@ static void sssraid_free_ioq_ptcmds(struct sssraid_ioc *sdioc) ...@@ -1382,7 +1405,7 @@ static void sssraid_free_ioq_ptcmds(struct sssraid_ioc *sdioc)
static void sssraid_delete_io_queues(struct sssraid_ioc *sdioc) static void sssraid_delete_io_queues(struct sssraid_ioc *sdioc)
{ {
u16 queues = sdioc->init_done_queue_cnt - 1; u16 queues = sdioc->init_done_queue_cnt - SSSRAID_ADM_QUEUE_NUM;
u8 opcode = SSSRAID_ADM_DELETE_SQ; u8 opcode = SSSRAID_ADM_DELETE_SQ;
u16 i, pass; u16 i, pass;
...@@ -1391,7 +1414,7 @@ static void sssraid_delete_io_queues(struct sssraid_ioc *sdioc) ...@@ -1391,7 +1414,7 @@ static void sssraid_delete_io_queues(struct sssraid_ioc *sdioc)
return; return;
} }
if (sdioc->init_done_queue_cnt < 2) { if (sdioc->init_done_queue_cnt <= SSSRAID_ADM_QUEUE_NUM) {
ioc_err(sdioc, "Err: io queue has been delete\n"); ioc_err(sdioc, "Err: io queue has been delete\n");
return; return;
} }
...@@ -1669,8 +1692,10 @@ static void sssraid_free_resources(struct sssraid_ioc *sdioc) ...@@ -1669,8 +1692,10 @@ static void sssraid_free_resources(struct sssraid_ioc *sdioc)
void sssraid_cleanup_ioc(struct sssraid_ioc *sdioc, u8 re_init) void sssraid_cleanup_ioc(struct sssraid_ioc *sdioc, u8 re_init)
{ {
if (!re_init) if (!re_init) {
sssraid_free_disk_list(sdioc);
sssraid_free_ioq_ptcmds(sdioc); sssraid_free_ioq_ptcmds(sdioc);
}
sssraid_delete_io_queues(sdioc); sssraid_delete_io_queues(sdioc);
sssraid_disable_admin_queue(sdioc, !re_init); sssraid_disable_admin_queue(sdioc, !re_init);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/bsg-lib.h> #include <linux/bsg-lib.h>
#include <linux/sort.h> #include <linux/sort.h>
#include <linux/msi.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
...@@ -307,7 +308,7 @@ void sssraid_cleanup_fwevt_list(struct sssraid_ioc *sdioc) ...@@ -307,7 +308,7 @@ void sssraid_cleanup_fwevt_list(struct sssraid_ioc *sdioc)
*/ */
static int sssraid_npages_prp(struct sssraid_ioc *sdioc) static int sssraid_npages_prp(struct sssraid_ioc *sdioc)
{ {
u32 size = 1U << ((sdioc->ctrl_info->mdts) * 1U) << 12; u32 size = (1U << ((sdioc->ctrl_info->mdts) * 1U)) << 12;
u32 nprps = DIV_ROUND_UP(size + sdioc->page_size, sdioc->page_size); u32 nprps = DIV_ROUND_UP(size + sdioc->page_size, sdioc->page_size);
return DIV_ROUND_UP(PRP_ENTRY_SIZE * nprps, sdioc->page_size - PRP_ENTRY_SIZE); return DIV_ROUND_UP(PRP_ENTRY_SIZE * nprps, sdioc->page_size - PRP_ENTRY_SIZE);
...@@ -618,7 +619,7 @@ static int sssraid_setup_rw_cmd(struct sssraid_ioc *sdioc, ...@@ -618,7 +619,7 @@ static int sssraid_setup_rw_cmd(struct sssraid_ioc *sdioc,
} }
/* 6-byte READ(0x08) or WRITE(0x0A) cdb */ /* 6-byte READ(0x08) or WRITE(0x0A) cdb */
if (scmd->cmd_len == 6) { if (scmd->cmd_len == SCSI_6_BYTE_CDB_LEN) {
datalength = (u32)(scmd->cmnd[4] == 0 ? datalength = (u32)(scmd->cmnd[4] == 0 ?
IO_6_DEFAULT_TX_LEN : scmd->cmnd[4]); IO_6_DEFAULT_TX_LEN : scmd->cmnd[4]);
start_lba_lo = (u32)get_unaligned_be24(&scmd->cmnd[1]); start_lba_lo = (u32)get_unaligned_be24(&scmd->cmnd[1]);
...@@ -627,7 +628,7 @@ static int sssraid_setup_rw_cmd(struct sssraid_ioc *sdioc, ...@@ -627,7 +628,7 @@ static int sssraid_setup_rw_cmd(struct sssraid_ioc *sdioc,
} }
/* 10-byte READ(0x28) or WRITE(0x2A) cdb */ /* 10-byte READ(0x28) or WRITE(0x2A) cdb */
else if (scmd->cmd_len == 10) { else if (scmd->cmd_len == SCSI_10_BYTE_CDB_LEN) {
datalength = (u32)get_unaligned_be16(&scmd->cmnd[7]); datalength = (u32)get_unaligned_be16(&scmd->cmnd[7]);
start_lba_lo = get_unaligned_be32(&scmd->cmnd[2]); start_lba_lo = get_unaligned_be32(&scmd->cmnd[2]);
...@@ -636,7 +637,7 @@ static int sssraid_setup_rw_cmd(struct sssraid_ioc *sdioc, ...@@ -636,7 +637,7 @@ static int sssraid_setup_rw_cmd(struct sssraid_ioc *sdioc,
} }
/* 12-byte READ(0xA8) or WRITE(0xAA) cdb */ /* 12-byte READ(0xA8) or WRITE(0xAA) cdb */
else if (scmd->cmd_len == 12) { else if (scmd->cmd_len == SCSI_12_BYTE_CDB_LEN) {
datalength = get_unaligned_be32(&scmd->cmnd[6]); datalength = get_unaligned_be32(&scmd->cmnd[6]);
start_lba_lo = get_unaligned_be32(&scmd->cmnd[2]); start_lba_lo = get_unaligned_be32(&scmd->cmnd[2]);
...@@ -644,7 +645,7 @@ static int sssraid_setup_rw_cmd(struct sssraid_ioc *sdioc, ...@@ -644,7 +645,7 @@ static int sssraid_setup_rw_cmd(struct sssraid_ioc *sdioc,
control |= SSSRAID_RW_FUA; control |= SSSRAID_RW_FUA;
} }
/* 16-byte READ(0x88) or WRITE(0x8A) cdb */ /* 16-byte READ(0x88) or WRITE(0x8A) cdb */
else if (scmd->cmd_len == 16) { else if (scmd->cmd_len == SCSI_16_BYTE_CDB_LEN) {
datalength = get_unaligned_be32(&scmd->cmnd[10]); datalength = get_unaligned_be32(&scmd->cmnd[10]);
start_lba_lo = get_unaligned_be32(&scmd->cmnd[6]); start_lba_lo = get_unaligned_be32(&scmd->cmnd[6]);
start_lba_hi = get_unaligned_be32(&scmd->cmnd[2]); start_lba_hi = get_unaligned_be32(&scmd->cmnd[2]);
...@@ -1067,6 +1068,7 @@ bool sssraid_change_host_state(struct sssraid_ioc *sdioc, enum sssraid_state new ...@@ -1067,6 +1068,7 @@ bool sssraid_change_host_state(struct sssraid_ioc *sdioc, enum sssraid_state new
default: default:
break; break;
} }
if (change) if (change)
sdioc->state = newstate; sdioc->state = newstate;
spin_unlock_irqrestore(&sdioc->state_lock, flags); spin_unlock_irqrestore(&sdioc->state_lock, flags);
...@@ -1386,14 +1388,6 @@ static int sssraid_bsg_host_dispatch(struct bsg_job *job) ...@@ -1386,14 +1388,6 @@ static int sssraid_bsg_host_dispatch(struct bsg_job *job)
return 0; return 0;
} }
static inline void sssraid_remove_bsg(struct sssraid_ioc *sdioc)
{
if (sdioc->bsg_queue) {
bsg_unregister_queue(sdioc->bsg_queue);
blk_cleanup_queue(sdioc->bsg_queue);
}
}
static void sssraid_back_fault_cqe(struct sssraid_squeue *sqinfo, struct sssraid_completion *cqe) static void sssraid_back_fault_cqe(struct sssraid_squeue *sqinfo, struct sssraid_completion *cqe)
{ {
struct sssraid_ioc *sdioc = sqinfo->sdioc; struct sssraid_ioc *sdioc = sqinfo->sdioc;
...@@ -1462,6 +1456,17 @@ void sssraid_back_all_io(struct sssraid_ioc *sdioc) ...@@ -1462,6 +1456,17 @@ void sssraid_back_all_io(struct sssraid_ioc *sdioc)
} }
} }
static int sssraid_get_first_sibling(unsigned int cpu)
{
unsigned int ret;
ret = cpumask_first(topology_sibling_cpumask(cpu));
if (ret < nr_cpu_ids)
return ret;
return cpu;
}
/* /*
* static struct scsi_host_template sssraid_driver_template * static struct scsi_host_template sssraid_driver_template
*/ */
...@@ -1536,6 +1541,69 @@ static int sssraid_sysfs_host_reset(struct Scsi_Host *shost, int reset_type) ...@@ -1536,6 +1541,69 @@ static int sssraid_sysfs_host_reset(struct Scsi_Host *shost, int reset_type)
return ret; return ret;
} }
static int sssraid_map_queues(struct Scsi_Host *shost)
{
struct sssraid_ioc *sdioc = shost_priv(shost);
struct pci_dev *pdev = sdioc->pdev;
struct msi_desc *entry = NULL;
struct irq_affinity_desc *affinity = NULL;
struct blk_mq_tag_set *tag_set = &shost->tag_set;
struct blk_mq_queue_map *queue_map = &tag_set->map[HCTX_TYPE_DEFAULT];
const struct cpumask *node_mask = NULL;
unsigned int queue_offset = queue_map->queue_offset;
unsigned int *map = queue_map->mq_map;
unsigned int nr_queues = queue_map->nr_queues;
unsigned int node_id, node_id_last = 0xFFFFFFFF;
int cpu, first_sibling, cpu_index = 0;
u8 node_count = 0, i;
unsigned int node_id_array[100];
for_each_pci_msi_entry(entry, pdev) {
struct list_head *msi_list = &pdev->dev.msi_list;
if (list_is_last(msi_list, &entry->list))
goto get_next_numa_node;
if (entry->irq) {
affinity = entry->affinity;
node_mask = &affinity->mask;
cpu = cpumask_first(node_mask);
node_id = cpu_to_node(cpu);
if (node_id_last == node_id)
continue;
for (i = 0; i < node_count; i++) {
if (node_id == node_id_array[i])
goto get_next_numa_node;
}
node_id_array[node_count++] = node_id;
node_id_last = node_id;
}
get_next_numa_node:
continue;
}
for (i = 0; i < node_count; i++) {
node_mask = cpumask_of_node(node_id_array[i]);
dbgprint(sdioc, "NUMA_node = %d\n", node_id_array[i]);
for_each_cpu(cpu, node_mask) {
if (cpu_index < nr_queues) {
map[cpu_index++] = queue_offset + (cpu % nr_queues);
} else {
first_sibling = sssraid_get_first_sibling(cpu);
if (first_sibling == cpu)
map[cpu_index++] = queue_offset + (cpu % nr_queues);
else
map[cpu_index++] = map[first_sibling];
}
dbgprint(sdioc, "map[%d] = %d\n", cpu_index - 1, map[cpu_index - 1]);
}
}
return 0;
}
/* queuecommand call back */ /* queuecommand call back */
static int sssraid_qcmd(struct Scsi_Host *shost, static int sssraid_qcmd(struct Scsi_Host *shost,
struct scsi_cmnd *scmd) struct scsi_cmnd *scmd)
...@@ -1989,6 +2057,7 @@ static struct scsi_host_template sssraid_driver_template = { ...@@ -1989,6 +2057,7 @@ static struct scsi_host_template sssraid_driver_template = {
.name = "3SNIC Logic sssraid driver", .name = "3SNIC Logic sssraid driver",
.proc_name = "sssraid", .proc_name = "sssraid",
.queuecommand = sssraid_qcmd, .queuecommand = sssraid_qcmd,
.map_queues = sssraid_map_queues,
.slave_alloc = sssraid_slave_alloc, .slave_alloc = sssraid_slave_alloc,
.slave_destroy = sssraid_slave_destroy, .slave_destroy = sssraid_slave_destroy,
.slave_configure = sssraid_slave_configure, .slave_configure = sssraid_slave_configure,
...@@ -2026,7 +2095,7 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2026,7 +2095,7 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id)
struct sssraid_ioc *sdioc; struct sssraid_ioc *sdioc;
struct Scsi_Host *shost; struct Scsi_Host *shost;
int node; int node;
char bsg_name[15]; char bsg_name[BSG_NAME_SIZE];
int retval = 0; int retval = 0;
node = dev_to_node(&pdev->dev); node = dev_to_node(&pdev->dev);
...@@ -2038,14 +2107,15 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2038,14 +2107,15 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id)
shost = scsi_host_alloc(&sssraid_driver_template, sizeof(*sdioc)); shost = scsi_host_alloc(&sssraid_driver_template, sizeof(*sdioc));
if (!shost) { if (!shost) {
retval = -ENODEV; retval = -ENODEV;
ioc_err(sdioc, "err: failed to allocate scsi host\n"); dev_err(&pdev->dev, "err: failed to allocate scsi host\n");
goto shost_failed; goto shost_failed;
} }
sdioc = shost_priv(shost); sdioc = shost_priv(shost);
sdioc->numa_node = node; sdioc->numa_node = node;
sdioc->instance = shost->host_no; /* for device instance */ sdioc->instance = shost->host_no; /* for device instance */
sprintf(sdioc->name, "%s%d", SSSRAID_DRIVER_NAME, sdioc->instance); snprintf(sdioc->name, sizeof(sdioc->name),
"%s%d", SSSRAID_DRIVER_NAME, sdioc->instance);
init_rwsem(&sdioc->devices_rwsem); init_rwsem(&sdioc->devices_rwsem);
spin_lock_init(&sdioc->state_lock); spin_lock_init(&sdioc->state_lock);
...@@ -2055,7 +2125,6 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2055,7 +2125,6 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id)
INIT_LIST_HEAD(&sdioc->fwevt_list); INIT_LIST_HEAD(&sdioc->fwevt_list);
// logging_level = 1; //garden test
sdioc->logging_level = logging_level; /* according to log_debug_switch*/ sdioc->logging_level = logging_level; /* according to log_debug_switch*/
snprintf(sdioc->fwevt_worker_name, sizeof(sdioc->fwevt_worker_name), snprintf(sdioc->fwevt_worker_name, sizeof(sdioc->fwevt_worker_name),
...@@ -2063,8 +2132,7 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2063,8 +2132,7 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id)
sdioc->fwevt_worker_thread = alloc_ordered_workqueue( sdioc->fwevt_worker_thread = alloc_ordered_workqueue(
sdioc->fwevt_worker_name, WQ_MEM_RECLAIM); sdioc->fwevt_worker_name, WQ_MEM_RECLAIM);
if (!sdioc->fwevt_worker_thread) { if (!sdioc->fwevt_worker_thread) {
ioc_err(sdioc, "failure at %s:%d/%s()!\n", ioc_err(sdioc, "err: fail to alloc workqueue for fwevt_work!\n");
__FILE__, __LINE__, __func__);
retval = -ENODEV; retval = -ENODEV;
goto out_fwevtthread_failed; goto out_fwevtthread_failed;
} }
...@@ -2073,8 +2141,7 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2073,8 +2141,7 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id)
sdioc->pdev = pdev; sdioc->pdev = pdev;
if (sssraid_init_ioc(sdioc, 0)) { if (sssraid_init_ioc(sdioc, 0)) {
ioc_err(sdioc, "failure at %s:%d/%s()!\n", ioc_err(sdioc, "err: failure at init sssraid_ioc!\n");
__FILE__, __LINE__, __func__);
retval = -ENODEV; retval = -ENODEV;
goto out_iocinit_failed; goto out_iocinit_failed;
} }
...@@ -2083,8 +2150,7 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2083,8 +2150,7 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id)
retval = scsi_add_host(shost, &pdev->dev); retval = scsi_add_host(shost, &pdev->dev);
if (retval) { if (retval) {
ioc_err(sdioc, "failure at %s:%d/%s()!\n", ioc_err(sdioc, "err: add shost to system failed!\n");
__FILE__, __LINE__, __func__);
goto addhost_failed; goto addhost_failed;
} }
...@@ -2092,16 +2158,22 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2092,16 +2158,22 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id)
sdioc->bsg_queue = bsg_setup_queue(&shost->shost_gendev, bsg_name, sdioc->bsg_queue = bsg_setup_queue(&shost->shost_gendev, bsg_name,
sssraid_bsg_host_dispatch, NULL, sssraid_cmd_size(sdioc)); sssraid_bsg_host_dispatch, NULL, sssraid_cmd_size(sdioc));
if (IS_ERR(sdioc->bsg_queue)) { if (IS_ERR(sdioc->bsg_queue)) {
ioc_err(sdioc, "err: setup bsg failed\n"); ioc_err(sdioc, "err: setup bsg failed!\n");
sdioc->bsg_queue = NULL; sdioc->bsg_queue = NULL;
goto bsg_setup_failed; goto bsg_setup_failed;
} }
sssraid_change_host_state(sdioc, SSSRAID_LIVE); if (!sssraid_change_host_state(sdioc, SSSRAID_LIVE)) {
retval = -ENODEV;
ioc_err(sdioc, "err: change host state failed!\n");
goto sssraid_state_change_failed;
}
scsi_scan_host(shost); scsi_scan_host(shost);
return retval; return retval;
sssraid_state_change_failed:
bsg_remove_queue(sdioc->bsg_queue);
bsg_setup_failed: bsg_setup_failed:
scsi_remove_host(shost); scsi_remove_host(shost);
addhost_failed: addhost_failed:
...@@ -2117,15 +2189,15 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2117,15 +2189,15 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id)
static void sssraid_remove(struct pci_dev *pdev) static void sssraid_remove(struct pci_dev *pdev)
{ {
struct Scsi_Host *shost = pci_get_drvdata(pdev); struct Scsi_Host *shost = pci_get_drvdata(pdev);
struct sssraid_ioc *sdioc; struct sssraid_ioc *sdioc = NULL;
if (!shost) if (!shost) {
dev_err(&pdev->dev, "driver probe process failed, remove not be allowed.\n");
return; return;
}
ioc_info(sdioc, "sssraid remove entry\n");
sdioc = shost_priv(shost); sdioc = shost_priv(shost);
ioc_info(sdioc, "sssraid remove entry\n");
sssraid_change_host_state(sdioc, SSSRAID_DELETING); sssraid_change_host_state(sdioc, SSSRAID_DELETING);
if (!pci_device_is_present(pdev)) if (!pci_device_is_present(pdev))
...@@ -2134,7 +2206,7 @@ static void sssraid_remove(struct pci_dev *pdev) ...@@ -2134,7 +2206,7 @@ static void sssraid_remove(struct pci_dev *pdev)
sssraid_cleanup_fwevt_list(sdioc); sssraid_cleanup_fwevt_list(sdioc);
destroy_workqueue(sdioc->fwevt_worker_thread); destroy_workqueue(sdioc->fwevt_worker_thread);
sssraid_remove_bsg(sdioc); bsg_remove_queue(sdioc->bsg_queue);
scsi_remove_host(shost); scsi_remove_host(shost);
sssraid_cleanup_ioc(sdioc, 0); sssraid_cleanup_ioc(sdioc, 0);
...@@ -2323,14 +2395,14 @@ static int __init sssraid_init(void) ...@@ -2323,14 +2395,14 @@ static int __init sssraid_init(void)
static void __exit sssraid_exit(void) static void __exit sssraid_exit(void)
{ {
pci_unregister_driver(&sssraid_pci_driver);
class_destroy(sssraid_class);
pr_info("Unloading %s version %s\n", SSSRAID_DRIVER_NAME, pr_info("Unloading %s version %s\n", SSSRAID_DRIVER_NAME,
SSSRAID_DRIVER_VERSION); SSSRAID_DRIVER_VERSION);
class_destroy(sssraid_class);
pci_unregister_driver(&sssraid_pci_driver);
} }
MODULE_AUTHOR("liangry1@3snic.com"); MODULE_AUTHOR("steven.song@3snic.com");
MODULE_DESCRIPTION("3SNIC Information Technology SSSRAID Driver"); MODULE_DESCRIPTION("3SNIC Information Technology SSSRAID Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_VERSION(SSSRAID_DRIVER_VERSION); MODULE_VERSION(SSSRAID_DRIVER_VERSION);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册