From: Stephen Hemminger <shemminger@osdl.org>
To: Jeff Garzik <jgarzik@pobox.com>
Cc: "Kok, Auke" <auke-jan.h.kok@intel.com>,
netdev@vger.kernel.org, "Brandeburg,
Jesse" <jesse.brandeburg@intel.com>,
"Kok, Auke" <auke@foo-projects.org>,
"Ronciak, John" <john.ronciak@intel.com>
Subject: Re: [PATCH 12/23] e1000: Maybe stop TX if not enough free descriptors
Date: Tue, 19 Sep 2006 12:50:19 -0700 [thread overview]
Message-ID: <20060919125019.316d3790@localhost.localdomain> (raw)
In-Reply-To: <45104719.9080708@pobox.com>
My preference would be for drivers not to use LLTX (except loopback) and just
use the dev->xmit_lock via netif_tx_lock if possible. Something like this for e1000.
Subject: [PATCH] e1000 no lltx
Get rid of lockless transmit for e1000. Use netif_tx_lock instead
of having to do locking in device. For NAPI this is trivial but
for the non-NAPI case it means scheduling a tasklet to do Tx
cleanup
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
---
drivers/net/e1000/e1000.h | 7 +++--
drivers/net/e1000/e1000_main.c | 53 ++++++++++++++++++++++------------------
2 files changed, 33 insertions(+), 27 deletions(-)
87a7c62864818350ebb7da73f26e1dc49c5eb2e5
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 98afa9c..9de6519 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -190,7 +190,6 @@ struct e1000_tx_ring {
/* array of buffer information structs */
struct e1000_buffer *buffer_info;
- spinlock_t tx_lock;
uint16_t tdh;
uint16_t tdt;
boolean_t last_tx_tso;
@@ -251,9 +250,8 @@ struct e1000_adapter {
uint16_t link_speed;
uint16_t link_duplex;
spinlock_t stats_lock;
-#ifdef CONFIG_E1000_NAPI
spinlock_t tx_queue_lock;
-#endif
+
atomic_t irq_sem;
struct work_struct reset_task;
uint8_t fc_autoneg;
@@ -263,6 +261,9 @@ struct e1000_adapter {
/* TX */
struct e1000_tx_ring *tx_ring; /* One per active queue */
+#ifndef CONFIG_E1000_NAPI
+ struct tasklet_struct tx_tasklet;
+#endif
unsigned long tx_queue_len;
uint32_t txd_cmd;
uint32_t tx_int_delay;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index acf818b..8eb38a7 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -158,6 +158,7 @@ static boolean_t e1000_clean_rx_irq_ps(s
struct e1000_rx_ring *rx_ring,
int *work_done, int work_to_do);
#else
+static void e1000_tx_tasklet(unsigned long arg);
static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
struct e1000_rx_ring *rx_ring);
static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
@@ -811,8 +812,6 @@ e1000_probe(struct pci_dev *pdev,
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
- netdev->features |= NETIF_F_LLTX;
-
adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
/* initialize eeprom parameters */
@@ -1155,8 +1154,11 @@ e1000_sw_init(struct e1000_adapter *adap
dev_hold(&adapter->polling_netdev[i]);
set_bit(__LINK_STATE_START, &adapter->polling_netdev[i].state);
}
- spin_lock_init(&adapter->tx_queue_lock);
+#else
+ adapter->tx_tasklet.func = &e1000_tx_tasklet;
+ adapter->tx_tasklet.data = (unsigned long) adapter;
#endif
+ spin_lock_init(&adapter->tx_queue_lock);
atomic_set(&adapter->irq_sem, 1);
spin_lock_init(&adapter->stats_lock);
@@ -1407,7 +1409,6 @@ setup_tx_desc_die:
txdr->next_to_use = 0;
txdr->next_to_clean = 0;
- spin_lock_init(&txdr->tx_lock);
return 0;
}
@@ -1991,6 +1992,23 @@ e1000_clean_tx_ring(struct e1000_adapter
writel(0, adapter->hw.hw_addr + tx_ring->tdt);
}
+#ifndef CONFIG_E1000_NAPI
+static void
+e1000_tx_tasklet(unsigned long arg)
+{
+ struct e1000_adapter *adapter = (struct e1000_adapter *) arg;
+ int i;
+
+ if (!spin_trylock(&adapter->tx_queue_lock))
+ return;
+
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ e1000_clean_tx_irq(adapter, adapter->tx_ring);
+
+ spin_unlock(&adapter->tx_queue_lock);
+}
+#endif
+
/**
* e1000_clean_all_tx_rings - Free Tx Buffers for all queues
* @adapter: board private structure
@@ -2902,7 +2920,6 @@ e1000_xmit_frame(struct sk_buff *skb, st
unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
unsigned int tx_flags = 0;
unsigned int len = skb->len;
- unsigned long flags;
unsigned int nr_frags = 0;
unsigned int mss = 0;
int count = 0;
@@ -2996,18 +3013,10 @@ e1000_xmit_frame(struct sk_buff *skb, st
(adapter->hw.mac_type == e1000_82573))
e1000_transfer_dhcp_info(adapter, skb);
- local_irq_save(flags);
- if (!spin_trylock(&tx_ring->tx_lock)) {
- /* Collision - tell upper layer to requeue */
- local_irq_restore(flags);
- return NETDEV_TX_LOCKED;
- }
-
/* need: count + 2 desc gap to keep tail from touching
* head, otherwise try next time */
if (unlikely(E1000_DESC_UNUSED(tx_ring) < count + 2)) {
netif_stop_queue(netdev);
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_BUSY;
}
@@ -3015,7 +3024,6 @@ e1000_xmit_frame(struct sk_buff *skb, st
if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
netif_stop_queue(netdev);
mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_BUSY;
}
}
@@ -3030,7 +3038,6 @@ e1000_xmit_frame(struct sk_buff *skb, st
tso = e1000_tso(adapter, tx_ring, skb);
if (tso < 0) {
dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_OK;
}
@@ -3056,7 +3063,6 @@ e1000_xmit_frame(struct sk_buff *skb, st
if (unlikely(E1000_DESC_UNUSED(tx_ring) < MAX_SKB_FRAGS + 2))
netif_stop_queue(netdev);
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_OK;
}
@@ -3438,10 +3444,11 @@ e1000_intr(int irq, void *data, struct p
}
for (i = 0; i < E1000_MAX_INTR; i++)
- if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
- !e1000_clean_tx_irq(adapter, adapter->tx_ring)))
+ if (!adapter->clean_rx(adapter, adapter->rx_ring))
break;
+ tasklet_schedule(&adapter->tx_tasklet);
+
if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
e1000_irq_enable(adapter);
@@ -3546,13 +3553,11 @@ e1000_clean_tx_irq(struct e1000_adapter
tx_ring->next_to_clean = i;
#define TX_WAKE_THRESHOLD 32
- if (unlikely(cleaned && netif_queue_stopped(netdev) &&
- netif_carrier_ok(netdev))) {
- spin_lock(&tx_ring->tx_lock);
- if (netif_queue_stopped(netdev) &&
- (E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))
+ if (unlikely(cleaned && netif_carrier_ok(netdev))) {
+ netif_tx_lock(netdev);
+ if (E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)
netif_wake_queue(netdev);
- spin_unlock(&tx_ring->tx_lock);
+ netif_tx_unlock(netdev);
}
if (adapter->detect_tx_hung) {
--
1.1.3
next prev parent reply other threads:[~2006-09-19 19:50 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-09-19 17:26 [PATCH 00/23] e100, e1000, ixgb updates Kok, Auke
2006-09-19 17:28 ` [PATCH 01/23] e100, e1000, ixgb: update copyright header and remove LICENSE Kok, Auke
2006-09-19 17:28 ` [PATCH 02/23] e100, e1000, ixgb: Fix an impossible memory overwrite bug Kok, Auke
2006-09-19 17:28 ` [PATCH 03/23] e100: Add debugging code for cb cleaning and csum failures Kok, Auke
2006-09-19 19:10 ` Jeff Garzik
2006-09-19 22:25 ` Auke Kok
2006-09-19 21:33 ` Dave Jones
2006-09-19 21:40 ` Jeff Garzik
2006-09-19 21:46 ` Dave Jones
2006-09-19 22:21 ` Auke Kok
2006-09-19 17:28 ` [PATCH 04/23] e100: rework WoL and shutdown handling Kok, Auke
2006-09-19 19:10 ` Jeff Garzik
2006-09-19 20:25 ` Auke Kok
2006-09-19 20:30 ` Jeff Garzik
2006-09-19 21:38 ` Auke Kok
2006-09-19 17:28 ` [PATCH 05/23] e1000: rename flow control symbols Kok, Auke
2006-09-19 19:11 ` Jeff Garzik
2006-09-19 21:45 ` Auke Kok
2006-09-19 17:28 ` [PATCH 06/23] e1000: add enums for several link properties Kok, Auke
2006-09-19 17:28 ` [PATCH 07/23] e1000: remove unused code and make symbols static Kok, Auke
2006-09-19 19:28 ` Jeff Garzik
2006-09-19 17:28 ` [PATCH 08/23] e1000: add multicast stats counters Kok, Auke
2006-09-19 19:28 ` Jeff Garzik
2006-09-19 17:28 ` [PATCH 09/23] e1000: allow ethtool to pass arbitrary speed advertisment Kok, Auke
2006-09-19 17:28 ` [PATCH 10/23] e1000: Fix MANC detection for PCIE adapters Kok, Auke
2006-09-19 19:31 ` Jeff Garzik
2006-09-19 17:28 ` [PATCH 11/23] e1000: Jumbo frames fixes for 82573 Kok, Auke
2006-09-19 19:32 ` Jeff Garzik
2006-09-20 15:37 ` Auke Kok
2006-09-19 17:28 ` [PATCH 12/23] e1000: Maybe stop TX if not enough free descriptors Kok, Auke
2006-09-19 19:37 ` Jeff Garzik
2006-09-19 19:38 ` Jeff Garzik
2006-09-19 19:50 ` Stephen Hemminger [this message]
2006-09-19 20:45 ` Jeff Garzik
2006-09-19 20:59 ` Stephen Hemminger
2006-09-19 23:26 ` Auke Kok
2006-09-19 23:59 ` Stephen Hemminger
2006-09-20 15:30 ` Auke Kok
[not found] ` <4807377b0609211659mb0cb308hcbc78520148300a1@mail.gmail.com>
2006-09-24 11:30 ` Fwd: " Herbert Xu
2006-09-19 17:29 ` [PATCH 13/23] e1000: gather hardware bit tweaks Kok, Auke
2006-09-19 19:36 ` Jeff Garzik
2006-09-27 20:12 ` Auke Kok
2006-09-19 17:29 ` [PATCH 14/23] e1000: handle manageability for pci-e adapters at PHY powerdown Kok, Auke
2006-09-19 19:39 ` Jeff Garzik
2006-09-19 17:29 ` [PATCH 15/23] e1000: add PCI-E capability detection code Kok, Auke
2006-09-19 17:29 ` [PATCH 16/23] e1000: reduce RAR entries available for ICH8 Kok, Auke
2006-09-19 19:39 ` Jeff Garzik
2006-09-19 17:29 ` [PATCH 17/23] e1000: driver state fixes (race fix) Kok, Auke
2006-09-19 19:40 ` Jeff Garzik
2006-09-19 17:29 ` [PATCH 18/23] e1000: revert 'e1000: Remove 0x1000 as supported device' Kok, Auke
2006-09-19 19:40 ` Jeff Garzik
2006-09-19 20:34 ` Auke Kok
2006-09-19 20:43 ` Jeff Garzik
2006-09-19 17:29 ` [PATCH 19/23] e1000: rework polarity, NVM, eeprom code and fixes Kok, Auke
2006-09-19 17:29 ` [PATCH 20/23] e1000: don't strip vlan ID if 8021q claims it Kok, Auke
2006-09-19 19:41 ` Jeff Garzik
2006-09-19 17:29 ` [PATCH 21/23] ixgb: combine more rx descriptors to improve performance Kok, Auke
2006-09-19 17:29 ` [PATCH 22/23] ixgb: convert to netdev_priv(netdev) Kok, Auke
2006-09-19 17:29 ` [PATCH 23/23] e100, e1000, ixgb: increment version numbers Kok, Auke
2006-09-19 19:41 ` Jeff Garzik
2006-09-19 19:42 ` [PATCH 00/23] e100, e1000, ixgb updates Jeff Garzik
2006-09-19 21:06 ` Auke Kok
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060919125019.316d3790@localhost.localdomain \
--to=shemminger@osdl.org \
--cc=auke-jan.h.kok@intel.com \
--cc=auke@foo-projects.org \
--cc=jesse.brandeburg@intel.com \
--cc=jgarzik@pobox.com \
--cc=john.ronciak@intel.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.