OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From: Felix Fietkau <nbd@nbd.name> |
2 | Date: Sun, 12 Apr 2015 10:08:04 +0200 |
||
3 | Subject: [PATCH] bgmac: leave interrupts disabled as long as there is work |
||
4 | to do |
||
5 | |||
6 | Always poll rx and tx during NAPI poll instead of relying on the status |
||
7 | of the first interrupt. This prevents bgmac_poll from leaving unfinished |
||
8 | work around until the next IRQ. |
||
9 | In my tests this makes bridging/routing throughput under heavy load more |
||
10 | stable and ensures that no new IRQs arrive as long as bgmac_poll uses up |
||
11 | the entire budget. |
||
12 | |||
13 | Signed-off-by: Felix Fietkau <nbd@nbd.name> |
||
14 | --- |
||
15 | |||
16 | --- a/drivers/net/ethernet/broadcom/bgmac.c |
||
17 | +++ b/drivers/net/ethernet/broadcom/bgmac.c |
||
18 | @@ -1109,8 +1109,6 @@ static void bgmac_chip_reset(struct bgma |
||
19 | bgmac_phy_init(bgmac); |
||
20 | |||
21 | netdev_reset_queue(bgmac->net_dev); |
||
22 | - |
||
23 | - bgmac->int_status = 0; |
||
24 | } |
||
25 | |||
26 | static void bgmac_chip_intrs_on(struct bgmac *bgmac) |
||
27 | @@ -1225,14 +1223,13 @@ static irqreturn_t bgmac_interrupt(int i |
||
28 | if (!int_status) |
||
29 | return IRQ_NONE; |
||
30 | |||
31 | - /* Ack */ |
||
32 | - bgmac_write(bgmac, BGMAC_INT_STATUS, int_status); |
||
33 | + int_status &= ~(BGMAC_IS_TX0 | BGMAC_IS_RX); |
||
34 | + if (int_status) |
||
35 | + bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", int_status); |
||
36 | |||
37 | /* Disable new interrupts until handling existing ones */ |
||
38 | bgmac_chip_intrs_off(bgmac); |
||
39 | |||
40 | - bgmac->int_status = int_status; |
||
41 | - |
||
42 | napi_schedule(&bgmac->napi); |
||
43 | |||
44 | return IRQ_HANDLED; |
||
45 | @@ -1241,25 +1238,17 @@ static irqreturn_t bgmac_interrupt(int i |
||
46 | static int bgmac_poll(struct napi_struct *napi, int weight) |
||
47 | { |
||
48 | struct bgmac *bgmac = container_of(napi, struct bgmac, napi); |
||
49 | - struct bgmac_dma_ring *ring; |
||
50 | int handled = 0; |
||
51 | |||
52 | - if (bgmac->int_status & BGMAC_IS_TX0) { |
||
53 | - ring = &bgmac->tx_ring[0]; |
||
54 | - bgmac_dma_tx_free(bgmac, ring); |
||
55 | - bgmac->int_status &= ~BGMAC_IS_TX0; |
||
56 | - } |
||
57 | + /* Ack */ |
||
58 | + bgmac_write(bgmac, BGMAC_INT_STATUS, ~0); |
||
59 | |||
60 | - if (bgmac->int_status & BGMAC_IS_RX) { |
||
61 | - ring = &bgmac->rx_ring[0]; |
||
62 | - handled += bgmac_dma_rx_read(bgmac, ring, weight); |
||
63 | - bgmac->int_status &= ~BGMAC_IS_RX; |
||
64 | - } |
||
65 | + bgmac_dma_tx_free(bgmac, &bgmac->tx_ring[0]); |
||
66 | + handled += bgmac_dma_rx_read(bgmac, &bgmac->rx_ring[0], weight); |
||
67 | |||
68 | - if (bgmac->int_status) { |
||
69 | - bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", bgmac->int_status); |
||
70 | - bgmac->int_status = 0; |
||
71 | - } |
||
72 | + /* Poll again if more events arrived in the meantime */ |
||
73 | + if (bgmac_read(bgmac, BGMAC_INT_STATUS) & (BGMAC_IS_TX0 | BGMAC_IS_RX)) |
||
74 | + return handled; |
||
75 | |||
76 | if (handled < weight) { |
||
77 | napi_complete(napi); |
||
78 | --- a/drivers/net/ethernet/broadcom/bgmac.h |
||
79 | +++ b/drivers/net/ethernet/broadcom/bgmac.h |
||
80 | @@ -452,7 +452,6 @@ struct bgmac { |
||
81 | |||
82 | /* Int */ |
||
83 | u32 int_mask; |
||
84 | - u32 int_status; |
||
85 | |||
86 | /* Current MAC state */ |
||
87 | int mac_speed; |