Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Refactor interrupts #18

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion onic.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@
#define ONIC_MAX_QUEUES 64

/* state bits */
#define ONIC_ERROR_INTR 0
#define ONIC_MBOX_INTR 0
#define ONIC_USER_INTR 1
#define ONIC_ERROR_INTR 2

/* flag bits */
#define ONIC_FLAG_MASTER_PF 0
#define ONIC_FLAG_MBOX_INTR 1
#define ONIC_FLAG_USER_INTR 2

struct onic_tx_buffer {
struct sk_buff *skb;
Expand Down Expand Up @@ -81,6 +84,7 @@ struct onic_rx_queue {
};

struct onic_q_vector {
u16 qid;
u16 vid;
struct onic_private *priv;
struct cpumask affinity_mask;
Expand Down
137 changes: 88 additions & 49 deletions onic_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ static irqreturn_t onic_q_handler(int irq, void *dev_id)
{
struct onic_q_vector *vec = dev_id;
struct onic_private *priv = vec->priv;
u16 qid = vec->vid;
u16 qid = vec->qid;
struct onic_rx_queue *rxq = priv->rx_queue[qid];
bool debug = 0;
if (debug) dev_info(&priv->pdev->dev, "queue irq");
Expand All @@ -39,6 +39,13 @@ static irqreturn_t onic_q_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}

static irqreturn_t onic_mailbox_handler(int irq, void *dev_id)
{
struct onic_private *priv = dev_id;
dev_info(&priv->pdev->dev, "mailbox irq");
return IRQ_HANDLED;
}

static irqreturn_t onic_user_handler(int irq, void *dev_id)
{
struct onic_private *priv = dev_id;
Expand Down Expand Up @@ -76,28 +83,30 @@ static irqreturn_t onic_error_thread_fn(int irq, void *dev_id)
/**
* onic_init_q_vector - clear a queue vector
* @priv: pointer to driver private data
* @vid: vector ID
* @idx: queue vector index
**/
static void onic_clear_q_vector(struct onic_private *priv, u16 vid)
static void onic_clear_q_vector(struct onic_private *priv, int idx)
{
struct onic_q_vector *vec = priv->q_vector[vid];
struct onic_q_vector *vec = priv->q_vector[idx];

if (!vec)
return;
free_irq(pci_irq_vector(priv->pdev, vid), vec);
free_irq(pci_irq_vector(priv->pdev, vec->vid), vec);
kfree(vec);
priv->q_vector[idx] = NULL;
}

/**
* onic_init_q_vector - initialize a queue vector
* @priv: pointer to driver private data
* @qid: queue ID
* @vid: vector ID
*
* This function does the following: allocate coherent DMA region for interrupt
* aggregation ring, register NAPI instances, and initialize relevant QDMA
* interrupt registers. Return 0 on success, negative on failure
**/
static int onic_init_q_vector(struct onic_private *priv, u16 vid)
static int onic_init_q_vector(struct onic_private *priv, u16 qid, u16 vid)
{
struct pci_dev *pdev = priv->pdev;
struct onic_q_vector *vec;
Expand All @@ -109,8 +118,9 @@ static int onic_init_q_vector(struct onic_private *priv, u16 vid)
return -ENOMEM;
vec->priv = priv;
vec->vid = vid;
vec->qid = qid;

snprintf(name, ONIC_MAX_IRQ_NAME, "%s-%d", priv->netdev->name, vid);
snprintf(name, ONIC_MAX_IRQ_NAME, "%s-%d", priv->netdev->name, qid);
rv = request_irq(pci_irq_vector(pdev, vid), onic_q_handler,
0, name, vec);
if (rv < 0) {
Expand All @@ -119,13 +129,13 @@ static int onic_init_q_vector(struct onic_private *priv, u16 vid)
}

/* setup affinity mask and node */
/* cpu = vid % num_online_cpus(); */
/* cpu = qid % num_online_cpus(); */
/* cpumask_set_cpu(cpu, &vec->affinity_mask); */
/* vec->numa_node = node; */

dev_info(&pdev->dev, "Setup IRQ vector %d with name %s",
pci_irq_vector(pdev, vid), name);
priv->q_vector[vid] = vec;
priv->q_vector[qid] = vec;

return 0;
}
Expand All @@ -137,16 +147,20 @@ static int onic_init_q_vector(struct onic_private *priv, u16 vid)
* Attempt to acquire a suitable range of MSI-X vector interrupts. Return 0 on
* success, and negative on error.
*
* For every PF, a minimum of 2 vectors are required for proper operation, one
* for queue interrupt and one for user interreupt. The master PF requires one
* additional vector for global error interrupt.
* For every PF, 1 optional mailbox interrupt, 1 optional user interrupt and at
* least 1 queue interupt is required. The master PF requires one additional
* vector for global error interrupt.
**/
static int onic_acquire_msix_vectors(struct onic_private *priv)
{
int vectors, non_q_vectors;

vectors = ONIC_MAX_QUEUES;
non_q_vectors = 1;
non_q_vectors = 0;
if (test_bit(ONIC_FLAG_MBOX_INTR, priv->flags))
non_q_vectors++;
if (test_bit(ONIC_FLAG_USER_INTR, priv->flags))
non_q_vectors++;
if (test_bit(ONIC_FLAG_MASTER_PF, priv->flags))
non_q_vectors++;
vectors += non_q_vectors;
Expand Down Expand Up @@ -207,36 +221,56 @@ void onic_clear_capacity(struct onic_private *priv)
int onic_init_interrupt(struct onic_private *priv)
{
struct pci_dev *pdev = priv->pdev;
int vid, rv;
u16 qid, vid;
int rv;

for (vid = 0; vid < priv->num_q_vectors; ++vid) {
rv = onic_init_q_vector(priv, vid);
if (rv < 0)
vid = 0;
if (test_bit(ONIC_FLAG_MBOX_INTR, priv->flags)) {
rv = request_irq(pci_irq_vector(pdev, vid),
onic_mailbox_handler, 0, "onic-mailbox", priv);
if (rv < 0) {
dev_err(&pdev->dev,
"Failed to setup mailbox interrupt");
goto clear_interrupt;
}
set_bit(ONIC_MBOX_INTR, priv->state);
vid++;
}

rv = request_threaded_irq(pci_irq_vector(pdev, vid),
onic_user_handler, onic_user_thread_fn,
0, "onic-user", priv);
if (rv < 0) {
dev_err(&pdev->dev, "Failed to setup user interrupt");
goto clear_interrupt;
if (test_bit(ONIC_FLAG_USER_INTR, priv->flags)) {
rv = request_threaded_irq(pci_irq_vector(pdev, vid),
onic_user_handler,
onic_user_thread_fn, 0, "onic-user",
priv);
if (rv < 0) {
dev_err(&pdev->dev, "Failed to setup user interrupt");
goto clear_interrupt;
}
set_bit(ONIC_USER_INTR, priv->state);
vid++;
}
set_bit(ONIC_USER_INTR, priv->state);

if (!test_bit(ONIC_FLAG_MASTER_PF, priv->flags))
return 0;
if (test_bit(ONIC_FLAG_MASTER_PF, priv->flags)) {
rv = request_threaded_irq(pci_irq_vector(pdev, vid),
onic_error_handler,
onic_error_thread_fn, 0, "onic-error",
priv);
if (rv < 0) {
dev_err(&pdev->dev, "Failed to setup error interrupt");
goto clear_interrupt;
}
onic_qdma_init_error_interrupt(priv->hw.qdma, vid);
set_bit(ONIC_ERROR_INTR, priv->state);
vid++;
}

vid++;
rv = request_threaded_irq(pci_irq_vector(pdev, vid),
onic_error_handler, onic_error_thread_fn,
0, "onic-error", priv);
if (rv < 0) {
dev_err(&pdev->dev, "Failed to setup error interrupt");
goto clear_interrupt;
for (qid = 0; qid < priv->num_q_vectors; qid++) {
rv = onic_init_q_vector(priv, qid, vid);
if (rv < 0) {
goto clear_interrupt;
}
vid++;
}
onic_qdma_init_error_interrupt(priv->hw.qdma, vid);
set_bit(ONIC_ERROR_INTR, priv->state);

return 0;

Expand All @@ -247,22 +281,27 @@ int onic_init_interrupt(struct onic_private *priv)

void onic_clear_interrupt(struct onic_private *priv)
{
u8 master_pf = test_bit(ONIC_FLAG_MASTER_PF, priv->flags);
int vid = (master_pf) ?
priv->num_q_vectors + 1 :
priv->num_q_vectors;

if (master_pf) {
if (test_bit(ONIC_ERROR_INTR, priv->state)) {
free_irq(pci_irq_vector(priv->pdev, vid), priv);
onic_qdma_clear_error_interrupt(priv->hw.qdma);
}
vid--;
int vid, i;

vid = 0;
if (test_bit(ONIC_FLAG_MBOX_INTR, priv->flags) &&
test_bit(ONIC_MBOX_INTR, priv->state)) {
free_irq(pci_irq_vector(priv->pdev, vid), priv);
vid++;
}

if (test_bit(ONIC_FLAG_USER_INTR, priv->flags) &&
test_bit(ONIC_USER_INTR, priv->state)) {
free_irq(pci_irq_vector(priv->pdev, vid), priv);
vid++;
}

if (test_bit(ONIC_USER_INTR, priv->state))
if (test_bit(ONIC_FLAG_MASTER_PF, priv->flags) &&
test_bit(ONIC_ERROR_INTR, priv->state)) {
free_irq(pci_irq_vector(priv->pdev, vid), priv);
onic_qdma_clear_error_interrupt(priv->hw.qdma);
}

while (vid--)
onic_clear_q_vector(priv, vid);
for (i = 0; i < priv->num_q_vectors; i++)
onic_clear_q_vector(priv, i);
}
19 changes: 6 additions & 13 deletions onic_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,6 @@ static int onic_init_tx_queue(struct onic_private *priv, u16 qid)
struct onic_tx_queue *q;
struct onic_ring *ring;
struct onic_qdma_h2c_param param;
u16 vid;
u32 size, real_count;
int rv;
bool debug = 0;
Expand All @@ -361,11 +360,8 @@ static int onic_init_tx_queue(struct onic_private *priv, u16 qid)
if (!q)
return -ENOMEM;

/* evenly assign to TX queues available vectors */
vid = qid % priv->num_q_vectors;

q->netdev = dev;
q->vector = priv->q_vector[vid];
q->vector = priv->q_vector[qid];
q->qid = qid;

ring = &q->ring;
Expand Down Expand Up @@ -398,7 +394,7 @@ static int onic_init_tx_queue(struct onic_private *priv, u16 qid)
/* initialize QDMA H2C queue */
param.rngcnt_idx = rngcnt_idx;
param.dma_addr = ring->dma_addr;
param.vid = vid;
param.vid = priv->q_vector[qid]->vid;
rv = onic_qdma_init_tx_queue(priv->hw.qdma, qid, &param);
if (rv < 0)
goto clear_tx_queue;
Expand Down Expand Up @@ -459,7 +455,6 @@ static int onic_init_rx_queue(struct onic_private *priv, u16 qid)
struct onic_rx_queue *q;
struct onic_ring *ring;
struct onic_qdma_c2h_param param;
u16 vid;
u32 size, real_count;
int i, rv;
bool debug = 0;
Expand All @@ -474,11 +469,8 @@ static int onic_init_rx_queue(struct onic_private *priv, u16 qid)
if (!q)
return -ENOMEM;

/* evenly assign to RX queues available vectors */
vid = qid % priv->num_q_vectors;

q->netdev = dev;
q->vector = priv->q_vector[vid];
q->vector = priv->q_vector[qid];
q->qid = qid;

/* allocate DMA memory for RX descriptor ring */
Expand Down Expand Up @@ -563,13 +555,14 @@ static int onic_init_rx_queue(struct onic_private *priv, u16 qid)
param.cmpl_desc_sz = 0;
param.desc_dma_addr = q->desc_ring.dma_addr;
param.cmpl_dma_addr = q->cmpl_ring.dma_addr;
param.vid = vid;
param.vid = priv->q_vector[qid]->vid;
if (debug)
netdev_info(
dev,
"bufsz_idx %u, desc_rngcnt_idx %u, cmpl_rngcnt_idx %u, desc_dma_addr 0x%llx, cmpl_dma_addr 0x%llx, vid %d",
bufsz_idx, desc_rngcnt_idx, cmpl_rngcnt_idx,
q->desc_ring.dma_addr, q->cmpl_ring.dma_addr, vid);
q->desc_ring.dma_addr, q->cmpl_ring.dma_addr,
priv->q_vector[qid]->vid);

rv = onic_qdma_init_rx_queue(priv->hw.qdma, qid, &param);
if (rv < 0)
Expand Down