diff options
author | Joakim Tjernlund <Joakim.Tjernlund@transmode.se> | 2009-04-17 08:03:48 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-04-21 05:07:17 -0400 |
commit | 0cededf3ffbb775c3716aa1d246338fdc24b1259 (patch) | |
tree | b8606da4301258e2919a0d5322988cde856661fc | |
parent | d035fbccc4edd2bd69d9314faf03ba832b85a1d7 (diff) |
ucc_geth: Move freeing of TX packets to NAPI context
This will make the system alot more responsive while ping flooding the
ucc_geth ethernet interface.
Also set NAPI weight to 64 as this is a common value.
Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ucc_geth.c | 31 | ||||
-rw-r--r-- | drivers/net/ucc_geth.h | 1 |
2 files changed, 11 insertions, 21 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index d3f39e86eb95..98f961e92ca9 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -3216,7 +3216,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) | |||
3216 | dev->stats.tx_packets++; | 3216 | dev->stats.tx_packets++; |
3217 | 3217 | ||
3218 | /* Free the sk buffer associated with this TxBD */ | 3218 | /* Free the sk buffer associated with this TxBD */ |
3219 | dev_kfree_skb_irq(ugeth-> | 3219 | dev_kfree_skb(ugeth-> |
3220 | tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]); | 3220 | tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]); |
3221 | ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL; | 3221 | ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL; |
3222 | ugeth->skb_dirtytx[txQ] = | 3222 | ugeth->skb_dirtytx[txQ] = |
@@ -3250,9 +3250,15 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget) | |||
3250 | for (i = 0; i < ug_info->numQueuesRx; i++) | 3250 | for (i = 0; i < ug_info->numQueuesRx; i++) |
3251 | howmany += ucc_geth_rx(ugeth, i, budget - howmany); | 3251 | howmany += ucc_geth_rx(ugeth, i, budget - howmany); |
3252 | 3252 | ||
3253 | /* Tx event processing */ | ||
3254 | spin_lock(&ugeth->lock); | ||
3255 | for (i = 0; i < ug_info->numQueuesTx; i++) | ||
3256 | ucc_geth_tx(ugeth->ndev, i); | ||
3257 | spin_unlock(&ugeth->lock); | ||
3258 | |||
3253 | if (howmany < budget) { | 3259 | if (howmany < budget) { |
3254 | napi_complete(napi); | 3260 | napi_complete(napi); |
3255 | setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS); | 3261 | setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS | UCCE_TX_EVENTS); |
3256 | } | 3262 | } |
3257 | 3263 | ||
3258 | return howmany; | 3264 | return howmany; |
@@ -3266,8 +3272,6 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) | |||
3266 | struct ucc_geth_info *ug_info; | 3272 | struct ucc_geth_info *ug_info; |
3267 | register u32 ucce; | 3273 | register u32 ucce; |
3268 | register u32 uccm; | 3274 | register u32 uccm; |
3269 | register u32 tx_mask; | ||
3270 | u8 i; | ||
3271 | 3275 | ||
3272 | ugeth_vdbg("%s: IN", __func__); | 3276 | ugeth_vdbg("%s: IN", __func__); |
3273 | 3277 | ||
@@ -3281,27 +3285,14 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) | |||
3281 | out_be32(uccf->p_ucce, ucce); | 3285 | out_be32(uccf->p_ucce, ucce); |
3282 | 3286 | ||
3283 | /* check for receive events that require processing */ | 3287 | /* check for receive events that require processing */ |
3284 | if (ucce & UCCE_RX_EVENTS) { | 3288 | if (ucce & (UCCE_RX_EVENTS | UCCE_TX_EVENTS)) { |
3285 | if (napi_schedule_prep(&ugeth->napi)) { | 3289 | if (napi_schedule_prep(&ugeth->napi)) { |
3286 | uccm &= ~UCCE_RX_EVENTS; | 3290 | uccm &= ~(UCCE_RX_EVENTS | UCCE_TX_EVENTS); |
3287 | out_be32(uccf->p_uccm, uccm); | 3291 | out_be32(uccf->p_uccm, uccm); |
3288 | __napi_schedule(&ugeth->napi); | 3292 | __napi_schedule(&ugeth->napi); |
3289 | } | 3293 | } |
3290 | } | 3294 | } |
3291 | 3295 | ||
3292 | /* Tx event processing */ | ||
3293 | if (ucce & UCCE_TX_EVENTS) { | ||
3294 | spin_lock(&ugeth->lock); | ||
3295 | tx_mask = UCC_GETH_UCCE_TXB0; | ||
3296 | for (i = 0; i < ug_info->numQueuesTx; i++) { | ||
3297 | if (ucce & tx_mask) | ||
3298 | ucc_geth_tx(dev, i); | ||
3299 | ucce &= ~tx_mask; | ||
3300 | tx_mask <<= 1; | ||
3301 | } | ||
3302 | spin_unlock(&ugeth->lock); | ||
3303 | } | ||
3304 | |||
3305 | /* Errors and other events */ | 3296 | /* Errors and other events */ |
3306 | if (ucce & UCCE_OTHER) { | 3297 | if (ucce & UCCE_OTHER) { |
3307 | if (ucce & UCC_GETH_UCCE_BSY) | 3298 | if (ucce & UCC_GETH_UCCE_BSY) |
@@ -3734,7 +3725,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3734 | dev->netdev_ops = &ucc_geth_netdev_ops; | 3725 | dev->netdev_ops = &ucc_geth_netdev_ops; |
3735 | dev->watchdog_timeo = TX_TIMEOUT; | 3726 | dev->watchdog_timeo = TX_TIMEOUT; |
3736 | INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work); | 3727 | INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work); |
3737 | netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT); | 3728 | netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, 64); |
3738 | dev->mtu = 1500; | 3729 | dev->mtu = 1500; |
3739 | 3730 | ||
3740 | ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT); | 3731 | ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT); |
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index 2f8ee7c87efe..602764799df0 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h | |||
@@ -852,7 +852,6 @@ struct ucc_geth_hardware_statistics { | |||
852 | /* Driver definitions */ | 852 | /* Driver definitions */ |
853 | #define TX_BD_RING_LEN 0x10 | 853 | #define TX_BD_RING_LEN 0x10 |
854 | #define RX_BD_RING_LEN 0x10 | 854 | #define RX_BD_RING_LEN 0x10 |
855 | #define UCC_GETH_DEV_WEIGHT TX_BD_RING_LEN | ||
856 | 855 | ||
857 | #define TX_RING_MOD_MASK(size) (size-1) | 856 | #define TX_RING_MOD_MASK(size) (size-1) |
858 | #define RX_RING_MOD_MASK(size) (size-1) | 857 | #define RX_RING_MOD_MASK(size) (size-1) |