diff options
author | Frank Pavlic <fpavlic@de.ibm.com> | 2006-02-07 11:04:36 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-02-17 16:16:39 -0500 |
commit | 0d613a27cc753bfacd20e6eaa2183bb7fef4c76e (patch) | |
tree | 670fc8e8a703874c2c7b8626fb646679389fce1b /drivers/s390 | |
parent | ca5b0ec8ae9f11c85d1f27b19f182a054303f324 (diff) |
[PATCH] s390: lcs performance enhancements
[patch 1/2] s390: lcs performance enhancements
From: Klaus Wacker <kdwacker@de.ibm.com>
- When flood pinging (with large packet size) an LCS device,
about 90 % of all packets are dropped by driver.
- increased number of lcs IO buffers to 32.
- use netif_stop_queue/netif_wake_queue in lcs_start_xmit routine
- don't lock the whole xmit routine but just the piece of code where
tx_buffer is touched.
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
lcs.c | 31 +++++++++++++++++--------------
lcs.h | 2 +-
2 files changed, 18 insertions(+), 15 deletions(-)
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/net/lcs.c | 31 | ||||
-rw-r--r-- | drivers/s390/net/lcs.h | 2 |
2 files changed, 18 insertions, 15 deletions
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 6229ba4995ad..9cf88d7201d3 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c | |||
@@ -98,9 +98,9 @@ lcs_register_debug_facility(void) | |||
98 | return -ENOMEM; | 98 | return -ENOMEM; |
99 | } | 99 | } |
100 | debug_register_view(lcs_dbf_setup, &debug_hex_ascii_view); | 100 | debug_register_view(lcs_dbf_setup, &debug_hex_ascii_view); |
101 | debug_set_level(lcs_dbf_setup, 4); | 101 | debug_set_level(lcs_dbf_setup, 2); |
102 | debug_register_view(lcs_dbf_trace, &debug_hex_ascii_view); | 102 | debug_register_view(lcs_dbf_trace, &debug_hex_ascii_view); |
103 | debug_set_level(lcs_dbf_trace, 4); | 103 | debug_set_level(lcs_dbf_trace, 2); |
104 | return 0; | 104 | return 0; |
105 | } | 105 | } |
106 | 106 | ||
@@ -1292,9 +1292,8 @@ lcs_set_multicast_list(struct net_device *dev) | |||
1292 | LCS_DBF_TEXT(4, trace, "setmulti"); | 1292 | LCS_DBF_TEXT(4, trace, "setmulti"); |
1293 | card = (struct lcs_card *) dev->priv; | 1293 | card = (struct lcs_card *) dev->priv; |
1294 | 1294 | ||
1295 | if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD)) { | 1295 | if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD)) |
1296 | schedule_work(&card->kernel_thread_starter); | 1296 | schedule_work(&card->kernel_thread_starter); |
1297 | } | ||
1298 | } | 1297 | } |
1299 | 1298 | ||
1300 | #endif /* CONFIG_IP_MULTICAST */ | 1299 | #endif /* CONFIG_IP_MULTICAST */ |
@@ -1459,6 +1458,8 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer) | |||
1459 | lcs_release_buffer(channel, buffer); | 1458 | lcs_release_buffer(channel, buffer); |
1460 | card = (struct lcs_card *) | 1459 | card = (struct lcs_card *) |
1461 | ((char *) channel - offsetof(struct lcs_card, write)); | 1460 | ((char *) channel - offsetof(struct lcs_card, write)); |
1461 | if (netif_queue_stopped(card->dev)) | ||
1462 | netif_wake_queue(card->dev); | ||
1462 | spin_lock(&card->lock); | 1463 | spin_lock(&card->lock); |
1463 | card->tx_emitted--; | 1464 | card->tx_emitted--; |
1464 | if (card->tx_emitted <= 0 && card->tx_buffer != NULL) | 1465 | if (card->tx_emitted <= 0 && card->tx_buffer != NULL) |
@@ -1478,6 +1479,7 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, | |||
1478 | struct net_device *dev) | 1479 | struct net_device *dev) |
1479 | { | 1480 | { |
1480 | struct lcs_header *header; | 1481 | struct lcs_header *header; |
1482 | int rc = 0; | ||
1481 | 1483 | ||
1482 | LCS_DBF_TEXT(5, trace, "hardxmit"); | 1484 | LCS_DBF_TEXT(5, trace, "hardxmit"); |
1483 | if (skb == NULL) { | 1485 | if (skb == NULL) { |
@@ -1492,10 +1494,8 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, | |||
1492 | card->stats.tx_carrier_errors++; | 1494 | card->stats.tx_carrier_errors++; |
1493 | return 0; | 1495 | return 0; |
1494 | } | 1496 | } |
1495 | if (netif_queue_stopped(dev) ) { | 1497 | netif_stop_queue(card->dev); |
1496 | card->stats.tx_dropped++; | 1498 | spin_lock(&card->lock); |
1497 | return -EBUSY; | ||
1498 | } | ||
1499 | if (card->tx_buffer != NULL && | 1499 | if (card->tx_buffer != NULL && |
1500 | card->tx_buffer->count + sizeof(struct lcs_header) + | 1500 | card->tx_buffer->count + sizeof(struct lcs_header) + |
1501 | skb->len + sizeof(u16) > LCS_IOBUFFERSIZE) | 1501 | skb->len + sizeof(u16) > LCS_IOBUFFERSIZE) |
@@ -1506,7 +1506,8 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, | |||
1506 | card->tx_buffer = lcs_get_buffer(&card->write); | 1506 | card->tx_buffer = lcs_get_buffer(&card->write); |
1507 | if (card->tx_buffer == NULL) { | 1507 | if (card->tx_buffer == NULL) { |
1508 | card->stats.tx_dropped++; | 1508 | card->stats.tx_dropped++; |
1509 | return -EBUSY; | 1509 | rc = -EBUSY; |
1510 | goto out; | ||
1510 | } | 1511 | } |
1511 | card->tx_buffer->callback = lcs_txbuffer_cb; | 1512 | card->tx_buffer->callback = lcs_txbuffer_cb; |
1512 | card->tx_buffer->count = 0; | 1513 | card->tx_buffer->count = 0; |
@@ -1518,13 +1519,18 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, | |||
1518 | header->type = card->lan_type; | 1519 | header->type = card->lan_type; |
1519 | header->slot = card->portno; | 1520 | header->slot = card->portno; |
1520 | memcpy(header + 1, skb->data, skb->len); | 1521 | memcpy(header + 1, skb->data, skb->len); |
1522 | spin_unlock(&card->lock); | ||
1521 | card->stats.tx_bytes += skb->len; | 1523 | card->stats.tx_bytes += skb->len; |
1522 | card->stats.tx_packets++; | 1524 | card->stats.tx_packets++; |
1523 | dev_kfree_skb(skb); | 1525 | dev_kfree_skb(skb); |
1524 | if (card->tx_emitted <= 0) | 1526 | netif_wake_queue(card->dev); |
1527 | spin_lock(&card->lock); | ||
1528 | if (card->tx_emitted <= 0 && card->tx_buffer != NULL) | ||
1525 | /* If this is the first tx buffer emit it immediately. */ | 1529 | /* If this is the first tx buffer emit it immediately. */ |
1526 | __lcs_emit_txbuffer(card); | 1530 | __lcs_emit_txbuffer(card); |
1527 | return 0; | 1531 | out: |
1532 | spin_unlock(&card->lock); | ||
1533 | return rc; | ||
1528 | } | 1534 | } |
1529 | 1535 | ||
1530 | static int | 1536 | static int |
@@ -1535,9 +1541,7 @@ lcs_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1535 | 1541 | ||
1536 | LCS_DBF_TEXT(5, trace, "pktxmit"); | 1542 | LCS_DBF_TEXT(5, trace, "pktxmit"); |
1537 | card = (struct lcs_card *) dev->priv; | 1543 | card = (struct lcs_card *) dev->priv; |
1538 | spin_lock(&card->lock); | ||
1539 | rc = __lcs_start_xmit(card, skb, dev); | 1544 | rc = __lcs_start_xmit(card, skb, dev); |
1540 | spin_unlock(&card->lock); | ||
1541 | return rc; | 1545 | return rc; |
1542 | } | 1546 | } |
1543 | 1547 | ||
@@ -2319,7 +2323,6 @@ __init lcs_init_module(void) | |||
2319 | PRINT_ERR("Initialization failed\n"); | 2323 | PRINT_ERR("Initialization failed\n"); |
2320 | return rc; | 2324 | return rc; |
2321 | } | 2325 | } |
2322 | |||
2323 | return 0; | 2326 | return 0; |
2324 | } | 2327 | } |
2325 | 2328 | ||
diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h index 08e60ad43916..2fad5e40c2e4 100644 --- a/drivers/s390/net/lcs.h +++ b/drivers/s390/net/lcs.h | |||
@@ -95,7 +95,7 @@ do { \ | |||
95 | */ | 95 | */ |
96 | #define LCS_ILLEGAL_OFFSET 0xffff | 96 | #define LCS_ILLEGAL_OFFSET 0xffff |
97 | #define LCS_IOBUFFERSIZE 0x5000 | 97 | #define LCS_IOBUFFERSIZE 0x5000 |
98 | #define LCS_NUM_BUFFS 8 /* needs to be power of 2 */ | 98 | #define LCS_NUM_BUFFS 32 /* needs to be power of 2 */ |
99 | #define LCS_MAC_LENGTH 6 | 99 | #define LCS_MAC_LENGTH 6 |
100 | #define LCS_INVALID_PORT_NO -1 | 100 | #define LCS_INVALID_PORT_NO -1 |
101 | #define LCS_LANCMD_TIMEOUT_DEFAULT 5 | 101 | #define LCS_LANCMD_TIMEOUT_DEFAULT 5 |