Commit 0c88a761 authored by Rick Farrington's avatar Rick Farrington Committed by David S. Miller

liquidio: use meaningful names for IRQs

All IRQs owned by the PF and VF drivers share the same nondescript name
"octeon"; this makes it difficult to setup interrupt affinity.

Change the IRQ names to reflect their specific purpose:

    LiquidIO<id>-<func>-<type>-<queue pair num>

Examples:
    LiquidIO0-pf0-rxtx-3
    LiquidIO1-vf1-rxtx-0
    LiquidIO0-pf0-aux

We cannot use netdev->name for naming the IRQs because:

    1.  Early during init, the PF and VF drivers require interrupts to
        send/receive control data from the NIC firmware; so the PF and VF
        must request IRQs long before the netdev struct is registered.

    2.  The IRQ name can only be specified at the time it is requested.
        It cannot be changed after that.
Signed-off-by: default avatarRick Farrington <ricardo.farrington@cavium.com>
Signed-off-by: default avatarFelix Manlunas <felix.manlunas@cavium.com>
Signed-off-by: default avatarSatanand Burla <satananda.burla@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b229487b
...@@ -1084,16 +1084,35 @@ static int octeon_setup_interrupt(struct octeon_device *oct) ...@@ -1084,16 +1084,35 @@ static int octeon_setup_interrupt(struct octeon_device *oct)
int i; int i;
int num_ioq_vectors; int num_ioq_vectors;
int num_alloc_ioq_vectors; int num_alloc_ioq_vectors;
char *queue_irq_names = NULL;
char *aux_irq_name = NULL;
if (OCTEON_CN23XX_PF(oct) && oct->msix_on) { if (OCTEON_CN23XX_PF(oct) && oct->msix_on) {
oct->num_msix_irqs = oct->sriov_info.num_pf_rings; oct->num_msix_irqs = oct->sriov_info.num_pf_rings;
/* one non ioq interrupt for handling sli_mac_pf_int_sum */ /* one non ioq interrupt for handling sli_mac_pf_int_sum */
oct->num_msix_irqs += 1; oct->num_msix_irqs += 1;
/* allocate storage for the names assigned to each irq */
oct->irq_name_storage =
kcalloc((MAX_IOQ_INTERRUPTS_PER_PF + 1), INTRNAMSIZ,
GFP_KERNEL);
if (!oct->irq_name_storage) {
dev_err(&oct->pci_dev->dev, "Irq name storage alloc failed...\n");
return -ENOMEM;
}
queue_irq_names = oct->irq_name_storage;
aux_irq_name = &queue_irq_names
[IRQ_NAME_OFF(MAX_IOQ_INTERRUPTS_PER_PF)];
oct->msix_entries = kcalloc( oct->msix_entries = kcalloc(
oct->num_msix_irqs, sizeof(struct msix_entry), GFP_KERNEL); oct->num_msix_irqs, sizeof(struct msix_entry), GFP_KERNEL);
if (!oct->msix_entries) if (!oct->msix_entries) {
return 1; dev_err(&oct->pci_dev->dev, "Memory Alloc failed...\n");
kfree(oct->irq_name_storage);
oct->irq_name_storage = NULL;
return -ENOMEM;
}
msix_entries = (struct msix_entry *)oct->msix_entries; msix_entries = (struct msix_entry *)oct->msix_entries;
/*Assumption is that pf msix vectors start from pf srn to pf to /*Assumption is that pf msix vectors start from pf srn to pf to
...@@ -1111,7 +1130,9 @@ static int octeon_setup_interrupt(struct octeon_device *oct) ...@@ -1111,7 +1130,9 @@ static int octeon_setup_interrupt(struct octeon_device *oct)
dev_err(&oct->pci_dev->dev, "unable to Allocate MSI-X interrupts\n"); dev_err(&oct->pci_dev->dev, "unable to Allocate MSI-X interrupts\n");
kfree(oct->msix_entries); kfree(oct->msix_entries);
oct->msix_entries = NULL; oct->msix_entries = NULL;
return 1; kfree(oct->irq_name_storage);
oct->irq_name_storage = NULL;
return num_alloc_ioq_vectors;
} }
dev_dbg(&oct->pci_dev->dev, "OCTEON: Enough MSI-X interrupts are allocated...\n"); dev_dbg(&oct->pci_dev->dev, "OCTEON: Enough MSI-X interrupts are allocated...\n");
...@@ -1119,9 +1140,12 @@ static int octeon_setup_interrupt(struct octeon_device *oct) ...@@ -1119,9 +1140,12 @@ static int octeon_setup_interrupt(struct octeon_device *oct)
/** For PF, there is one non-ioq interrupt handler */ /** For PF, there is one non-ioq interrupt handler */
num_ioq_vectors -= 1; num_ioq_vectors -= 1;
snprintf(aux_irq_name, INTRNAMSIZ,
"LiquidIO%u-pf%u-aux", oct->octeon_id, oct->pf_num);
irqret = request_irq(msix_entries[num_ioq_vectors].vector, irqret = request_irq(msix_entries[num_ioq_vectors].vector,
liquidio_legacy_intr_handler, 0, "octeon", liquidio_legacy_intr_handler, 0,
oct); aux_irq_name, oct);
if (irqret) { if (irqret) {
dev_err(&oct->pci_dev->dev, dev_err(&oct->pci_dev->dev,
"OCTEON: Request_irq failed for MSIX interrupt Error: %d\n", "OCTEON: Request_irq failed for MSIX interrupt Error: %d\n",
...@@ -1129,13 +1153,20 @@ static int octeon_setup_interrupt(struct octeon_device *oct) ...@@ -1129,13 +1153,20 @@ static int octeon_setup_interrupt(struct octeon_device *oct)
pci_disable_msix(oct->pci_dev); pci_disable_msix(oct->pci_dev);
kfree(oct->msix_entries); kfree(oct->msix_entries);
oct->msix_entries = NULL; oct->msix_entries = NULL;
return 1; kfree(oct->irq_name_storage);
oct->irq_name_storage = NULL;
return irqret;
} }
for (i = 0; i < num_ioq_vectors; i++) { for (i = 0; i < num_ioq_vectors; i++) {
snprintf(&queue_irq_names[IRQ_NAME_OFF(i)], INTRNAMSIZ,
"LiquidIO%u-pf%u-rxtx-%u",
oct->octeon_id, oct->pf_num, i);
irqret = request_irq(msix_entries[i].vector, irqret = request_irq(msix_entries[i].vector,
liquidio_msix_intr_handler, 0, liquidio_msix_intr_handler, 0,
"octeon", &oct->ioq_vector[i]); &queue_irq_names[IRQ_NAME_OFF(i)],
&oct->ioq_vector[i]);
if (irqret) { if (irqret) {
dev_err(&oct->pci_dev->dev, dev_err(&oct->pci_dev->dev,
"OCTEON: Request_irq failed for MSIX interrupt Error: %d\n", "OCTEON: Request_irq failed for MSIX interrupt Error: %d\n",
...@@ -1155,7 +1186,9 @@ static int octeon_setup_interrupt(struct octeon_device *oct) ...@@ -1155,7 +1186,9 @@ static int octeon_setup_interrupt(struct octeon_device *oct)
pci_disable_msix(oct->pci_dev); pci_disable_msix(oct->pci_dev);
kfree(oct->msix_entries); kfree(oct->msix_entries);
oct->msix_entries = NULL; oct->msix_entries = NULL;
return 1; kfree(oct->irq_name_storage);
oct->irq_name_storage = NULL;
return irqret;
} }
oct->ioq_vector[i].vector = msix_entries[i].vector; oct->ioq_vector[i].vector = msix_entries[i].vector;
/* assign the cpu mask for this msix interrupt vector */ /* assign the cpu mask for this msix interrupt vector */
...@@ -1173,15 +1206,29 @@ static int octeon_setup_interrupt(struct octeon_device *oct) ...@@ -1173,15 +1206,29 @@ static int octeon_setup_interrupt(struct octeon_device *oct)
else else
oct->flags |= LIO_FLAG_MSI_ENABLED; oct->flags |= LIO_FLAG_MSI_ENABLED;
/* allocate storage for the names assigned to the irq */
oct->irq_name_storage = kcalloc(1, INTRNAMSIZ, GFP_KERNEL);
if (!oct->irq_name_storage)
return -ENOMEM;
queue_irq_names = oct->irq_name_storage;
snprintf(&queue_irq_names[IRQ_NAME_OFF(0)], INTRNAMSIZ,
"LiquidIO%u-pf%u-rxtx-%u",
oct->octeon_id, oct->pf_num, 0);
irqret = request_irq(oct->pci_dev->irq, irqret = request_irq(oct->pci_dev->irq,
liquidio_legacy_intr_handler, IRQF_SHARED, liquidio_legacy_intr_handler,
"octeon", oct); IRQF_SHARED,
&queue_irq_names[IRQ_NAME_OFF(0)], oct);
if (irqret) { if (irqret) {
if (oct->flags & LIO_FLAG_MSI_ENABLED) if (oct->flags & LIO_FLAG_MSI_ENABLED)
pci_disable_msi(oct->pci_dev); pci_disable_msi(oct->pci_dev);
dev_err(&oct->pci_dev->dev, "Request IRQ failed with code: %d\n", dev_err(&oct->pci_dev->dev, "Request IRQ failed with code: %d\n",
irqret); irqret);
return 1; kfree(oct->irq_name_storage);
oct->irq_name_storage = NULL;
return irqret;
} }
} }
return 0; return 0;
...@@ -1449,6 +1496,9 @@ static void octeon_destroy_resources(struct octeon_device *oct) ...@@ -1449,6 +1496,9 @@ static void octeon_destroy_resources(struct octeon_device *oct)
pci_disable_msi(oct->pci_dev); pci_disable_msi(oct->pci_dev);
} }
kfree(oct->irq_name_storage);
oct->irq_name_storage = NULL;
/* fallthrough */ /* fallthrough */
case OCT_DEV_MSIX_ALLOC_VECTOR_DONE: case OCT_DEV_MSIX_ALLOC_VECTOR_DONE:
if (OCTEON_CN23XX_PF(oct)) if (OCTEON_CN23XX_PF(oct))
......
...@@ -780,6 +780,7 @@ liquidio_msix_intr_handler(int irq __attribute__((unused)), void *dev) ...@@ -780,6 +780,7 @@ liquidio_msix_intr_handler(int irq __attribute__((unused)), void *dev)
static int octeon_setup_interrupt(struct octeon_device *oct) static int octeon_setup_interrupt(struct octeon_device *oct)
{ {
struct msix_entry *msix_entries; struct msix_entry *msix_entries;
char *queue_irq_names = NULL;
int num_alloc_ioq_vectors; int num_alloc_ioq_vectors;
int num_ioq_vectors; int num_ioq_vectors;
int irqret; int irqret;
...@@ -788,10 +789,25 @@ static int octeon_setup_interrupt(struct octeon_device *oct) ...@@ -788,10 +789,25 @@ static int octeon_setup_interrupt(struct octeon_device *oct)
if (oct->msix_on) { if (oct->msix_on) {
oct->num_msix_irqs = oct->sriov_info.rings_per_vf; oct->num_msix_irqs = oct->sriov_info.rings_per_vf;
/* allocate storage for the names assigned to each irq */
oct->irq_name_storage =
kcalloc(MAX_IOQ_INTERRUPTS_PER_VF, INTRNAMSIZ,
GFP_KERNEL);
if (!oct->irq_name_storage) {
dev_err(&oct->pci_dev->dev, "Irq name storage alloc failed...\n");
return -ENOMEM;
}
queue_irq_names = oct->irq_name_storage;
oct->msix_entries = kcalloc( oct->msix_entries = kcalloc(
oct->num_msix_irqs, sizeof(struct msix_entry), GFP_KERNEL); oct->num_msix_irqs, sizeof(struct msix_entry), GFP_KERNEL);
if (!oct->msix_entries) if (!oct->msix_entries) {
return 1; dev_err(&oct->pci_dev->dev, "Memory Alloc failed...\n");
kfree(oct->irq_name_storage);
oct->irq_name_storage = NULL;
return -ENOMEM;
}
msix_entries = (struct msix_entry *)oct->msix_entries; msix_entries = (struct msix_entry *)oct->msix_entries;
...@@ -805,16 +821,23 @@ static int octeon_setup_interrupt(struct octeon_device *oct) ...@@ -805,16 +821,23 @@ static int octeon_setup_interrupt(struct octeon_device *oct)
dev_err(&oct->pci_dev->dev, "unable to Allocate MSI-X interrupts\n"); dev_err(&oct->pci_dev->dev, "unable to Allocate MSI-X interrupts\n");
kfree(oct->msix_entries); kfree(oct->msix_entries);
oct->msix_entries = NULL; oct->msix_entries = NULL;
return 1; kfree(oct->irq_name_storage);
oct->irq_name_storage = NULL;
return num_alloc_ioq_vectors;
} }
dev_dbg(&oct->pci_dev->dev, "OCTEON: Enough MSI-X interrupts are allocated...\n"); dev_dbg(&oct->pci_dev->dev, "OCTEON: Enough MSI-X interrupts are allocated...\n");
num_ioq_vectors = oct->num_msix_irqs; num_ioq_vectors = oct->num_msix_irqs;
for (i = 0; i < num_ioq_vectors; i++) { for (i = 0; i < num_ioq_vectors; i++) {
snprintf(&queue_irq_names[IRQ_NAME_OFF(i)], INTRNAMSIZ,
"LiquidIO%u-vf%u-rxtx-%u",
oct->octeon_id, oct->vf_num, i);
irqret = request_irq(msix_entries[i].vector, irqret = request_irq(msix_entries[i].vector,
liquidio_msix_intr_handler, 0, liquidio_msix_intr_handler, 0,
"octeon", &oct->ioq_vector[i]); &queue_irq_names[IRQ_NAME_OFF(i)],
&oct->ioq_vector[i]);
if (irqret) { if (irqret) {
dev_err(&oct->pci_dev->dev, dev_err(&oct->pci_dev->dev,
"OCTEON: Request_irq failed for MSIX interrupt Error: %d\n", "OCTEON: Request_irq failed for MSIX interrupt Error: %d\n",
...@@ -830,7 +853,9 @@ static int octeon_setup_interrupt(struct octeon_device *oct) ...@@ -830,7 +853,9 @@ static int octeon_setup_interrupt(struct octeon_device *oct)
pci_disable_msix(oct->pci_dev); pci_disable_msix(oct->pci_dev);
kfree(oct->msix_entries); kfree(oct->msix_entries);
oct->msix_entries = NULL; oct->msix_entries = NULL;
return 1; kfree(oct->irq_name_storage);
oct->irq_name_storage = NULL;
return irqret;
} }
oct->ioq_vector[i].vector = msix_entries[i].vector; oct->ioq_vector[i].vector = msix_entries[i].vector;
/* assign the cpu mask for this msix interrupt vector */ /* assign the cpu mask for this msix interrupt vector */
...@@ -975,6 +1000,8 @@ static void octeon_destroy_resources(struct octeon_device *oct) ...@@ -975,6 +1000,8 @@ static void octeon_destroy_resources(struct octeon_device *oct)
pci_disable_msix(oct->pci_dev); pci_disable_msix(oct->pci_dev);
kfree(oct->msix_entries); kfree(oct->msix_entries);
oct->msix_entries = NULL; oct->msix_entries = NULL;
kfree(oct->irq_name_storage);
oct->irq_name_storage = NULL;
} }
/* Soft reset the octeon device before exiting */ /* Soft reset the octeon device before exiting */
if (oct->pci_dev->reset_fn) if (oct->pci_dev->reset_fn)
......
...@@ -100,6 +100,11 @@ enum octeon_tag_type { ...@@ -100,6 +100,11 @@ enum octeon_tag_type {
#define BYTES_PER_DHLEN_UNIT 8 #define BYTES_PER_DHLEN_UNIT 8
#define MAX_REG_CNT 2000000U #define MAX_REG_CNT 2000000U
#define INTRNAMSIZ 32
#define IRQ_NAME_OFF(i) ((i) * INTRNAMSIZ)
#define MAX_IOQ_INTERRUPTS_PER_PF (64 * 2)
#define MAX_IOQ_INTERRUPTS_PER_VF (8 * 2)
static inline u32 incr_index(u32 index, u32 count, u32 max) static inline u32 incr_index(u32 index, u32 count, u32 max)
{ {
......
...@@ -517,6 +517,9 @@ struct octeon_device { ...@@ -517,6 +517,9 @@ struct octeon_device {
void *msix_entries; void *msix_entries;
/* when requesting IRQs, the names are stored here */
void *irq_name_storage;
struct octeon_sriov_info sriov_info; struct octeon_sriov_info sriov_info;
struct octeon_pf_vf_hs_word pfvf_hsword; struct octeon_pf_vf_hs_word pfvf_hsword;
......
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