1
0
Fork 0

epic100: use napi_complete_done()

Use napi_complete_done() instead of __napi_complete() to :

1) Get support of gro_flush_timeout if opt-in
2) Not rearm interrupts for busy-polling users.
3) use standard NAPI API.
4) get rid of baroque code and ease maintenance.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
hifive-unleashed-5.1
Eric Dumazet 2017-02-04 15:24:53 -08:00 committed by David S. Miller
parent ab1e7e1d26
commit 1fa8c5f33a
1 changed files with 7 additions and 24 deletions

View File

@ -264,7 +264,6 @@ struct epic_private {
spinlock_t lock; /* Group with Tx control cache line. */ spinlock_t lock; /* Group with Tx control cache line. */
spinlock_t napi_lock; spinlock_t napi_lock;
struct napi_struct napi; struct napi_struct napi;
unsigned int reschedule_in_poll;
unsigned int cur_tx, dirty_tx; unsigned int cur_tx, dirty_tx;
unsigned int cur_rx, dirty_rx; unsigned int cur_rx, dirty_rx;
@ -400,7 +399,6 @@ static int epic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
spin_lock_init(&ep->lock); spin_lock_init(&ep->lock);
spin_lock_init(&ep->napi_lock); spin_lock_init(&ep->napi_lock);
ep->reschedule_in_poll = 0;
/* Bring the chip out of low-power mode. */ /* Bring the chip out of low-power mode. */
ew32(GENCTL, 0x4200); ew32(GENCTL, 0x4200);
@ -1086,13 +1084,12 @@ static irqreturn_t epic_interrupt(int irq, void *dev_instance)
handled = 1; handled = 1;
if ((status & EpicNapiEvent) && !ep->reschedule_in_poll) { if (status & EpicNapiEvent) {
spin_lock(&ep->napi_lock); spin_lock(&ep->napi_lock);
if (napi_schedule_prep(&ep->napi)) { if (napi_schedule_prep(&ep->napi)) {
epic_napi_irq_off(dev, ep); epic_napi_irq_off(dev, ep);
__napi_schedule(&ep->napi); __napi_schedule(&ep->napi);
} else }
ep->reschedule_in_poll++;
spin_unlock(&ep->napi_lock); spin_unlock(&ep->napi_lock);
} }
status &= ~EpicNapiEvent; status &= ~EpicNapiEvent;
@ -1248,37 +1245,23 @@ static int epic_poll(struct napi_struct *napi, int budget)
{ {
struct epic_private *ep = container_of(napi, struct epic_private, napi); struct epic_private *ep = container_of(napi, struct epic_private, napi);
struct net_device *dev = ep->mii.dev; struct net_device *dev = ep->mii.dev;
int work_done = 0;
void __iomem *ioaddr = ep->ioaddr; void __iomem *ioaddr = ep->ioaddr;
int work_done;
rx_action:
epic_tx(dev, ep); epic_tx(dev, ep);
work_done += epic_rx(dev, budget); work_done = epic_rx(dev, budget);
epic_rx_err(dev, ep); epic_rx_err(dev, ep);
if (work_done < budget) { if (work_done < budget && napi_complete_done(napi, work_done)) {
unsigned long flags; unsigned long flags;
int more;
/* A bit baroque but it avoids a (space hungry) spin_unlock */
spin_lock_irqsave(&ep->napi_lock, flags); spin_lock_irqsave(&ep->napi_lock, flags);
more = ep->reschedule_in_poll; ew32(INTSTAT, EpicNapiEvent);
if (!more) { epic_napi_irq_on(dev, ep);
__napi_complete(napi);
ew32(INTSTAT, EpicNapiEvent);
epic_napi_irq_on(dev, ep);
} else
ep->reschedule_in_poll--;
spin_unlock_irqrestore(&ep->napi_lock, flags); spin_unlock_irqrestore(&ep->napi_lock, flags);
if (more)
goto rx_action;
} }
return work_done; return work_done;