cndm: Allocate IRQ structures in one block

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich
2026-01-01 22:04:13 -08:00
parent 107238cce2
commit eca44dc247
3 changed files with 24 additions and 21 deletions

View File

@@ -40,7 +40,7 @@ struct cndm_dev {
struct miscdevice misc_dev; struct miscdevice misc_dev;
int irq_count; int irq_count;
struct cndm_irq *irq[CNDM_MAX_IRQ]; struct cndm_irq *irq;
struct net_device *ndev[32]; struct net_device *ndev[32];

View File

@@ -24,29 +24,32 @@ int cndm_irq_init_pcie(struct cndm_dev *cdev)
struct pci_dev *pdev = cdev->pdev; struct pci_dev *pdev = cdev->pdev;
struct device *dev = cdev->dev; struct device *dev = cdev->dev;
int ret = 0; int ret = 0;
int irq_count;
int k; int k;
cdev->irq_count = pci_alloc_irq_vectors(pdev, 1, CNDM_MAX_IRQ, PCI_IRQ_MSI | PCI_IRQ_MSIX); cdev->irq_count = 0;
if (cdev->irq_count < 0) {
irq_count = pci_alloc_irq_vectors(pdev, 1, CNDM_MAX_IRQ, PCI_IRQ_MSI | PCI_IRQ_MSIX);
if (irq_count < 0) {
dev_err(dev, "Failed to allocate IRQs"); dev_err(dev, "Failed to allocate IRQs");
return -ENOMEM; return -ENOMEM;
} }
for (k = 0; k < cdev->irq_count; k++) { cdev->irq = kvzalloc(sizeof(*cdev->irq) * irq_count, GFP_KERNEL);
struct cndm_irq *irq; if (!cdev->irq) {
irq = kzalloc(sizeof(*irq), GFP_KERNEL);
if (!irq) {
ret = -ENOMEM; ret = -ENOMEM;
dev_err(dev, "Failed to allocate memory");
goto fail; goto fail;
} }
for (k = 0; k < irq_count; k++) {
struct cndm_irq *irq = &cdev->irq[k];
ATOMIC_INIT_NOTIFIER_HEAD(&irq->nh); ATOMIC_INIT_NOTIFIER_HEAD(&irq->nh);
ret = pci_request_irq(pdev, k, cndm_irq_handler, NULL, ret = pci_request_irq(pdev, k, cndm_irq_handler, NULL,
irq, "%s-%d", cdev->name, k); irq, "%s-%d", cdev->name, k);
if (ret < 0) { if (ret < 0) {
kfree(irq);
ret = -ENOMEM; ret = -ENOMEM;
dev_err(dev, "Failed to request IRQ %d", k); dev_err(dev, "Failed to request IRQ %d", k);
goto fail; goto fail;
@@ -54,7 +57,7 @@ int cndm_irq_init_pcie(struct cndm_dev *cdev)
irq->index = k; irq->index = k;
irq->irqn = pci_irq_vector(pdev, k); irq->irqn = pci_irq_vector(pdev, k);
cdev->irq[k] = irq; cdev->irq_count++;
} }
dev_info(dev, "Configured %d IRQs", cdev->irq_count); dev_info(dev, "Configured %d IRQs", cdev->irq_count);
@@ -70,14 +73,14 @@ void cndm_irq_deinit_pcie(struct cndm_dev *cdev)
struct pci_dev *pdev = cdev->pdev; struct pci_dev *pdev = cdev->pdev;
int k; int k;
for (k = 0; k < CNDM_MAX_IRQ; k++) for (k = 0; k < cdev->irq_count; k++)
{ pci_free_irq(pdev, k, &cdev->irq[k]);
if (cdev->irq[k]) {
pci_free_irq(pdev, k, cdev->irq[k]); cdev->irq_count = 0;
kfree(cdev->irq[k]);
cdev->irq[k] = NULL; if (cdev->irq)
} kvfree(cdev->irq);
} cdev->irq = NULL;
pci_free_irq_vectors(pdev); pci_free_irq_vectors(pdev);
} }

View File

@@ -210,7 +210,7 @@ struct net_device *cndm_create_netdev(struct cndm_dev *cdev, int port, void __io
priv->registered = 1; priv->registered = 1;
priv->irq_nb.notifier_call = cndm_netdev_irq; priv->irq_nb.notifier_call = cndm_netdev_irq;
priv->irq = cdev->irq[port % cdev->irq_count]; priv->irq = &cdev->irq[port % cdev->irq_count];
ret = atomic_notifier_chain_register(&priv->irq->nh, &priv->irq_nb); ret = atomic_notifier_chain_register(&priv->irq->nh, &priv->irq_nb);
if (ret) { if (ret) {
priv->irq = NULL; priv->irq = NULL;