net: ionic: Provide interrupt allocation support for the RDMA driver

RDMA driver needs an interrupt for an event queue. Export
function from net driver to allocate an interrupt.

Reviewed-by: Shannon Nelson <shannon.nelson@amd.com>
Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com>
Link: https://patch.msgid.link/20250903061606.4139957-6-abhijit.gangurde@amd.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
This commit is contained in:
Abhijit Gangurde 2025-09-03 11:45:57 +05:30 committed by Leon Romanovsky
parent 0e02faffdb
commit 2dc6a6a678
3 changed files with 62 additions and 32 deletions

View File

@ -32,6 +32,29 @@ struct ionic_admin_ctx {
union ionic_adminq_comp comp;
};
#define IONIC_INTR_INDEX_NOT_ASSIGNED -1
#define IONIC_INTR_NAME_MAX_SZ 32
/**
* struct ionic_intr_info - Interrupt information
* @name: Name identifier
* @rearm_count: Interrupt rearm count
* @index: Interrupt index position
* @vector: Interrupt number
* @dim_coal_hw: Interrupt coalesce value in hardware units
* @affinity_mask: CPU affinity mask
* @aff_notify: context for notification of IRQ affinity changes
*/
struct ionic_intr_info {
char name[IONIC_INTR_NAME_MAX_SZ];
u64 rearm_count;
unsigned int index;
unsigned int vector;
u32 dim_coal_hw;
cpumask_var_t *affinity_mask;
struct irq_affinity_notify aff_notify;
};
/**
* ionic_adminq_post_wait - Post an admin command and wait for response
* @lif: Logical interface
@ -63,4 +86,24 @@ int ionic_error_to_errno(enum ionic_status_code code);
*/
void ionic_request_rdma_reset(struct ionic_lif *lif);
/**
* ionic_intr_alloc - Reserve a device interrupt
* @lif: Logical interface
* @intr: Reserved ionic interrupt structure
*
* Reserve an interrupt index and get irq number for that index.
*
* Return: zero or negative error status
*/
int ionic_intr_alloc(struct ionic_lif *lif, struct ionic_intr_info *intr);
/**
* ionic_intr_free - Release a device interrupt index
* @lif: Logical interface
* @intr: Interrupt index
*
* Mark the interrupt index unused so that it can be reserved again.
*/
void ionic_intr_free(struct ionic_lif *lif, int intr);
#endif /* _IONIC_API_H_ */

View File

@ -274,19 +274,6 @@ struct ionic_queue {
char name[IONIC_QUEUE_NAME_MAX_SZ];
} ____cacheline_aligned_in_smp;
#define IONIC_INTR_INDEX_NOT_ASSIGNED -1
#define IONIC_INTR_NAME_MAX_SZ 32
struct ionic_intr_info {
char name[IONIC_INTR_NAME_MAX_SZ];
u64 rearm_count;
unsigned int index;
unsigned int vector;
u32 dim_coal_hw;
cpumask_var_t *affinity_mask;
struct irq_affinity_notify aff_notify;
};
struct ionic_cq {
struct ionic_lif *lif;
struct ionic_queue *bound_q;

View File

@ -244,29 +244,36 @@ static int ionic_request_irq(struct ionic_lif *lif, struct ionic_qcq *qcq)
0, intr->name, &qcq->napi);
}
static int ionic_intr_alloc(struct ionic_lif *lif, struct ionic_intr_info *intr)
int ionic_intr_alloc(struct ionic_lif *lif, struct ionic_intr_info *intr)
{
struct ionic *ionic = lif->ionic;
int index;
int index, err;
index = find_first_zero_bit(ionic->intrs, ionic->nintrs);
if (index == ionic->nintrs) {
netdev_warn(lif->netdev, "%s: no intr, index=%d nintrs=%d\n",
__func__, index, ionic->nintrs);
if (index == ionic->nintrs)
return -ENOSPC;
}
set_bit(index, ionic->intrs);
ionic_intr_init(&ionic->idev, intr, index);
err = ionic_bus_get_irq(ionic, intr->index);
if (err < 0) {
clear_bit(index, ionic->intrs);
return err;
}
intr->vector = err;
return 0;
}
EXPORT_SYMBOL_NS(ionic_intr_alloc, "NET_IONIC");
static void ionic_intr_free(struct ionic *ionic, int index)
void ionic_intr_free(struct ionic_lif *lif, int index)
{
if (index != IONIC_INTR_INDEX_NOT_ASSIGNED && index < ionic->nintrs)
clear_bit(index, ionic->intrs);
if (index != IONIC_INTR_INDEX_NOT_ASSIGNED && index < lif->ionic->nintrs)
clear_bit(index, lif->ionic->intrs);
}
EXPORT_SYMBOL_NS(ionic_intr_free, "NET_IONIC");
static void ionic_irq_aff_notify(struct irq_affinity_notify *notify,
const cpumask_t *mask)
@ -401,7 +408,7 @@ static void ionic_qcq_intr_free(struct ionic_lif *lif, struct ionic_qcq *qcq)
irq_set_affinity_hint(qcq->intr.vector, NULL);
devm_free_irq(lif->ionic->dev, qcq->intr.vector, &qcq->napi);
qcq->intr.vector = 0;
ionic_intr_free(lif->ionic, qcq->intr.index);
ionic_intr_free(lif, qcq->intr.index);
qcq->intr.index = IONIC_INTR_INDEX_NOT_ASSIGNED;
}
@ -511,13 +518,6 @@ static int ionic_alloc_qcq_interrupt(struct ionic_lif *lif, struct ionic_qcq *qc
goto err_out;
}
err = ionic_bus_get_irq(lif->ionic, qcq->intr.index);
if (err < 0) {
netdev_warn(lif->netdev, "no vector for %s: %d\n",
qcq->q.name, err);
goto err_out_free_intr;
}
qcq->intr.vector = err;
ionic_intr_mask_assert(lif->ionic->idev.intr_ctrl, qcq->intr.index,
IONIC_INTR_MASK_SET);
@ -546,7 +546,7 @@ static int ionic_alloc_qcq_interrupt(struct ionic_lif *lif, struct ionic_qcq *qc
return 0;
err_out_free_intr:
ionic_intr_free(lif->ionic, qcq->intr.index);
ionic_intr_free(lif, qcq->intr.index);
err_out:
return err;
}
@ -741,7 +741,7 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
err_out_free_irq:
if (flags & IONIC_QCQ_F_INTR) {
devm_free_irq(dev, new->intr.vector, &new->napi);
ionic_intr_free(lif->ionic, new->intr.index);
ionic_intr_free(lif, new->intr.index);
}
err_out_free_page_pool:
page_pool_destroy(new->q.page_pool);