Skip to content

Commit

Permalink
enic: do tx cleanup in napi poll
Browse files Browse the repository at this point in the history
Till now enic had been doing tx clean in isr.

Using napi infrastructure to move the tx clean up out of isr to softirq.
Now, wq isr schedules napi poll. In enic_poll_msix_wq we clean up the tx queus.

This is applicable only on MSIX. In INTx and MSI we use single napi to clean
both rx & tx queues.

Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Govindarajulu Varadarajan authored and David S. Miller committed Jun 23, 2014
1 parent 14747cd commit 4cfe878
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 36 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/cisco/enic/enic.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ struct enic {
unsigned int rq_count;
u64 rq_truncated_pkts;
u64 rq_bad_fcs;
struct napi_struct napi[ENIC_RQ_MAX];
struct napi_struct napi[ENIC_RQ_MAX + ENIC_WQ_MAX];

/* interrupt resource cache line section */
____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX];
Expand Down
88 changes: 53 additions & 35 deletions drivers/net/ethernet/cisco/enic/enic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,40 +316,15 @@ static irqreturn_t enic_isr_msi(int irq, void *data)
return IRQ_HANDLED;
}

static irqreturn_t enic_isr_msix_rq(int irq, void *data)
static irqreturn_t enic_isr_msix(int irq, void *data)
{
struct napi_struct *napi = data;

/* schedule NAPI polling for RQ cleanup */
napi_schedule(napi);

return IRQ_HANDLED;
}

static irqreturn_t enic_isr_msix_wq(int irq, void *data)
{
struct enic *enic = data;
unsigned int cq;
unsigned int intr;
unsigned int wq_work_to_do = -1; /* no limit */
unsigned int wq_work_done;
unsigned int wq_irq;

wq_irq = (u32)irq - enic->msix_entry[enic_msix_wq_intr(enic, 0)].vector;
cq = enic_cq_wq(enic, wq_irq);
intr = enic_msix_wq_intr(enic, wq_irq);

wq_work_done = vnic_cq_service(&enic->cq[cq],
wq_work_to_do, enic_wq_service, NULL);

vnic_intr_return_credits(&enic->intr[intr],
wq_work_done,
1 /* unmask intr */,
1 /* reset intr timer */);

return IRQ_HANDLED;
}

static irqreturn_t enic_isr_msix_err(int irq, void *data)
{
struct enic *enic = data;
Expand Down Expand Up @@ -1274,7 +1249,36 @@ int enic_busy_poll(struct napi_struct *napi)
}
#endif /* CONFIG_NET_RX_BUSY_POLL */

static int enic_poll_msix(struct napi_struct *napi, int budget)
static int enic_poll_msix_wq(struct napi_struct *napi, int budget)
{
struct net_device *netdev = napi->dev;
struct enic *enic = netdev_priv(netdev);
unsigned int wq_index = (napi - &enic->napi[0]) - enic->rq_count;
struct vnic_wq *wq = &enic->wq[wq_index];
unsigned int cq;
unsigned int intr;
unsigned int wq_work_to_do = -1; /* clean all desc possible */
unsigned int wq_work_done;
unsigned int wq_irq;

wq_irq = wq->index;
cq = enic_cq_wq(enic, wq_irq);
intr = enic_msix_wq_intr(enic, wq_irq);
wq_work_done = vnic_cq_service(&enic->cq[cq], wq_work_to_do,
enic_wq_service, NULL);

vnic_intr_return_credits(&enic->intr[intr], wq_work_done,
0 /* don't unmask intr */,
1 /* reset intr timer */);
if (!wq_work_done) {
napi_complete(napi);
vnic_intr_unmask(&enic->intr[intr]);
}

return 0;
}

static int enic_poll_msix_rq(struct napi_struct *napi, int budget)
{
struct net_device *netdev = napi->dev;
struct enic *enic = netdev_priv(netdev);
Expand Down Expand Up @@ -1399,17 +1403,19 @@ static int enic_request_intr(struct enic *enic)
snprintf(enic->msix[intr].devname,
sizeof(enic->msix[intr].devname),
"%.11s-rx-%d", netdev->name, i);
enic->msix[intr].isr = enic_isr_msix_rq;
enic->msix[intr].isr = enic_isr_msix;
enic->msix[intr].devid = &enic->napi[i];
}

for (i = 0; i < enic->wq_count; i++) {
int wq = enic_cq_wq(enic, i);

intr = enic_msix_wq_intr(enic, i);
snprintf(enic->msix[intr].devname,
sizeof(enic->msix[intr].devname),
"%.11s-tx-%d", netdev->name, i);
enic->msix[intr].isr = enic_isr_msix_wq;
enic->msix[intr].devid = enic;
enic->msix[intr].isr = enic_isr_msix;
enic->msix[intr].devid = &enic->napi[wq];
}

intr = enic_msix_err_intr(enic);
Expand Down Expand Up @@ -1585,7 +1591,9 @@ static int enic_open(struct net_device *netdev)
enic_busy_poll_init_lock(&enic->rq[i]);
napi_enable(&enic->napi[i]);
}

if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX)
for (i = 0; i < enic->wq_count; i++)
napi_enable(&enic->napi[enic_cq_wq(enic, i)]);
enic_dev_enable(enic);

for (i = 0; i < enic->intr_count; i++)
Expand Down Expand Up @@ -1633,6 +1641,9 @@ static int enic_stop(struct net_device *netdev)

netif_carrier_off(netdev);
netif_tx_disable(netdev);
if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX)
for (i = 0; i < enic->wq_count; i++)
napi_disable(&enic->napi[enic_cq_wq(enic, i)]);

if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic))
enic_dev_del_station_addr(enic);
Expand Down Expand Up @@ -1752,13 +1763,14 @@ static void enic_poll_controller(struct net_device *netdev)
case VNIC_DEV_INTR_MODE_MSIX:
for (i = 0; i < enic->rq_count; i++) {
intr = enic_msix_rq_intr(enic, i);
enic_isr_msix_rq(enic->msix_entry[intr].vector,
&enic->napi[i]);
enic_isr_msix(enic->msix_entry[intr].vector,
&enic->napi[i]);
}

for (i = 0; i < enic->wq_count; i++) {
intr = enic_msix_wq_intr(enic, i);
enic_isr_msix_wq(enic->msix_entry[intr].vector, enic);
enic_isr_msix(enic->msix_entry[intr].vector,
&enic->napi[enic_cq_wq(enic, i)]);
}

break;
Expand Down Expand Up @@ -2159,6 +2171,9 @@ static void enic_dev_deinit(struct enic *enic)
napi_hash_del(&enic->napi[i]);
netif_napi_del(&enic->napi[i]);
}
if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX)
for (i = 0; i < enic->wq_count; i++)
netif_napi_del(&enic->napi[enic_cq_wq(enic, i)]);

enic_free_vnic_resources(enic);
enic_clear_intr_mode(enic);
Expand Down Expand Up @@ -2229,9 +2244,12 @@ static int enic_dev_init(struct enic *enic)
case VNIC_DEV_INTR_MODE_MSIX:
for (i = 0; i < enic->rq_count; i++) {
netif_napi_add(netdev, &enic->napi[i],
enic_poll_msix, 64);
enic_poll_msix_rq, NAPI_POLL_WEIGHT);
napi_hash_add(&enic->napi[i]);
}
for (i = 0; i < enic->wq_count; i++)
netif_napi_add(netdev, &enic->napi[enic_cq_wq(enic, i)],
enic_poll_msix_wq, NAPI_POLL_WEIGHT);
break;
}

Expand Down

0 comments on commit 4cfe878

Please sign in to comment.