* [PATCH] TI DaVinci EMAC: Clear statistics register properly.
From: Sriramakrishnan @ 2009-10-07 12:44 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: srk-l0cyMroinI0,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/
The mechanism to clear the statistics register is dependent
on the status of GMIIEN bit in MAC control register. If the
GMIIEN bit is set, the stats registers are write to decrement.
If the GMIIEN bit is cleared, the stats registers are plain
read/write registers. The stats register clearing operation
must take into account the current state of GMIIEN as it
can be cleared when the interface is brought down.
With existing implementation logic, querying for interface stats
when the interface is down, can corrupt the statistics counters.
This patch examines the GMIIEN bit status in MAC_CONTROL
register before choosing an appropriate mask for clearing stats
registers.
Signed-off-by: Sriramakrishnan <srk-l0cyMroinI0@public.gmane.org>
Acked-by: Chaithrika U S <chaithrika-l0cyMroinI0@public.gmane.org>
---
This patch is generated against the tip of net-next-2.6.
drivers/net/davinci_emac.c | 36 ++++++++++++++++++++++++------------
1 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index a421ec0..a876dce 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -330,6 +330,9 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
#define EMAC_DM646X_MAC_EOI_C0_RXEN (0x01)
#define EMAC_DM646X_MAC_EOI_C0_TXEN (0x02)
+/* EMAC Stats Clear Mask */
+#define EMAC_STATS_CLR_MASK (0xFFFFFFFF)
+
/** net_buf_obj: EMAC network bufferdata structure
*
* EMAC network buffer data structure
@@ -2544,40 +2547,49 @@ static int emac_dev_stop(struct net_device *ndev)
static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev)
{
struct emac_priv *priv = netdev_priv(ndev);
+ u32 mac_control;
+ u32 stats_clear_mask;
/* update emac hardware stats and reset the registers*/
+ mac_control = emac_read(EMAC_MACCONTROL);
+
+ if (mac_control & EMAC_MACCONTROL_GMIIEN)
+ stats_clear_mask = EMAC_STATS_CLR_MASK;
+ else
+ stats_clear_mask = 0;
+
priv->net_dev_stats.multicast += emac_read(EMAC_RXMCASTFRAMES);
- emac_write(EMAC_RXMCASTFRAMES, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_RXMCASTFRAMES, stats_clear_mask);
priv->net_dev_stats.collisions += (emac_read(EMAC_TXCOLLISION) +
emac_read(EMAC_TXSINGLECOLL) +
emac_read(EMAC_TXMULTICOLL));
- emac_write(EMAC_TXCOLLISION, EMAC_ALL_MULTI_REG_VALUE);
- emac_write(EMAC_TXSINGLECOLL, EMAC_ALL_MULTI_REG_VALUE);
- emac_write(EMAC_TXMULTICOLL, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_TXCOLLISION, stats_clear_mask);
+ emac_write(EMAC_TXSINGLECOLL, stats_clear_mask);
+ emac_write(EMAC_TXMULTICOLL, stats_clear_mask);
priv->net_dev_stats.rx_length_errors += (emac_read(EMAC_RXOVERSIZED) +
emac_read(EMAC_RXJABBER) +
emac_read(EMAC_RXUNDERSIZED));
- emac_write(EMAC_RXOVERSIZED, EMAC_ALL_MULTI_REG_VALUE);
- emac_write(EMAC_RXJABBER, EMAC_ALL_MULTI_REG_VALUE);
- emac_write(EMAC_RXUNDERSIZED, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_RXOVERSIZED, stats_clear_mask);
+ emac_write(EMAC_RXJABBER, stats_clear_mask);
+ emac_write(EMAC_RXUNDERSIZED, stats_clear_mask);
priv->net_dev_stats.rx_over_errors += (emac_read(EMAC_RXSOFOVERRUNS) +
emac_read(EMAC_RXMOFOVERRUNS));
- emac_write(EMAC_RXSOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
- emac_write(EMAC_RXMOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_RXSOFOVERRUNS, stats_clear_mask);
+ emac_write(EMAC_RXMOFOVERRUNS, stats_clear_mask);
priv->net_dev_stats.rx_fifo_errors += emac_read(EMAC_RXDMAOVERRUNS);
- emac_write(EMAC_RXDMAOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_RXDMAOVERRUNS, stats_clear_mask);
priv->net_dev_stats.tx_carrier_errors +=
emac_read(EMAC_TXCARRIERSENSE);
- emac_write(EMAC_TXCARRIERSENSE, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_TXCARRIERSENSE, stats_clear_mask);
priv->net_dev_stats.tx_fifo_errors = emac_read(EMAC_TXUNDERRUN);
- emac_write(EMAC_TXUNDERRUN, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_TXUNDERRUN, stats_clear_mask);
return &priv->net_dev_stats;
}
--
1.6.2.4
^ permalink raw reply related
* [PATCH net-next-2.6] ixgbe: Use the instance of net_device_stats from net_device.
From: Ajit Khaparde @ 2009-10-07 12:43 UTC (permalink / raw)
To: davem, netdev
Since net_device has an instance of net_device_stats,
we can remove the instance of this from the private adapter structure.
Signed-off-by: Ajit Khaparde <ajitk@serverengines.com>
---
drivers/net/ixgbe/ixgbe.h | 1 -
drivers/net/ixgbe/ixgbe_ethtool.c | 40 +++++++++++++++++++-----------------
drivers/net/ixgbe/ixgbe_main.c | 26 ++++++++++++------------
3 files changed, 34 insertions(+), 33 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 28f32da..2b85416 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -340,7 +340,6 @@ struct ixgbe_adapter {
/* OS defined structs */
struct net_device *netdev;
struct pci_dev *pdev;
- struct net_device_stats net_stats;
u32 test_icr;
struct ixgbe_ring test_tx_ring;
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index fa314cb..987b41c 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -48,11 +48,13 @@ struct ixgbe_stats {
#define IXGBE_STAT(m) sizeof(((struct ixgbe_adapter *)0)->m), \
offsetof(struct ixgbe_adapter, m)
+#define IXGBE_NETDEV_STAT(m) sizeof(((struct net_device *)0)->m), \
+ offsetof(struct net_device, m)
static struct ixgbe_stats ixgbe_gstrings_stats[] = {
- {"rx_packets", IXGBE_STAT(net_stats.rx_packets)},
- {"tx_packets", IXGBE_STAT(net_stats.tx_packets)},
- {"rx_bytes", IXGBE_STAT(net_stats.rx_bytes)},
- {"tx_bytes", IXGBE_STAT(net_stats.tx_bytes)},
+ {"rx_packets", IXGBE_NETDEV_STAT(stats.rx_packets)},
+ {"tx_packets", IXGBE_NETDEV_STAT(stats.tx_packets)},
+ {"rx_bytes", IXGBE_NETDEV_STAT(stats.rx_bytes)},
+ {"tx_bytes", IXGBE_NETDEV_STAT(stats.tx_bytes)},
{"rx_pkts_nic", IXGBE_STAT(stats.gprc)},
{"tx_pkts_nic", IXGBE_STAT(stats.gptc)},
{"rx_bytes_nic", IXGBE_STAT(stats.gorc)},
@@ -60,26 +62,26 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"lsc_int", IXGBE_STAT(lsc_int)},
{"tx_busy", IXGBE_STAT(tx_busy)},
{"non_eop_descs", IXGBE_STAT(non_eop_descs)},
- {"rx_errors", IXGBE_STAT(net_stats.rx_errors)},
- {"tx_errors", IXGBE_STAT(net_stats.tx_errors)},
- {"rx_dropped", IXGBE_STAT(net_stats.rx_dropped)},
- {"tx_dropped", IXGBE_STAT(net_stats.tx_dropped)},
- {"multicast", IXGBE_STAT(net_stats.multicast)},
+ {"rx_errors", IXGBE_NETDEV_STAT(stats.rx_errors)},
+ {"tx_errors", IXGBE_NETDEV_STAT(stats.tx_errors)},
+ {"rx_dropped", IXGBE_NETDEV_STAT(stats.rx_dropped)},
+ {"tx_dropped", IXGBE_NETDEV_STAT(stats.tx_dropped)},
+ {"multicast", IXGBE_NETDEV_STAT(stats.multicast)},
{"broadcast", IXGBE_STAT(stats.bprc)},
{"rx_no_buffer_count", IXGBE_STAT(stats.rnbc[0]) },
- {"collisions", IXGBE_STAT(net_stats.collisions)},
- {"rx_over_errors", IXGBE_STAT(net_stats.rx_over_errors)},
- {"rx_crc_errors", IXGBE_STAT(net_stats.rx_crc_errors)},
- {"rx_frame_errors", IXGBE_STAT(net_stats.rx_frame_errors)},
+ {"collisions", IXGBE_NETDEV_STAT(stats.collisions)},
+ {"rx_over_errors", IXGBE_NETDEV_STAT(stats.rx_over_errors)},
+ {"rx_crc_errors", IXGBE_NETDEV_STAT(stats.rx_crc_errors)},
+ {"rx_frame_errors", IXGBE_NETDEV_STAT(stats.rx_frame_errors)},
{"hw_rsc_count", IXGBE_STAT(rsc_count)},
{"fdir_match", IXGBE_STAT(stats.fdirmatch)},
{"fdir_miss", IXGBE_STAT(stats.fdirmiss)},
- {"rx_fifo_errors", IXGBE_STAT(net_stats.rx_fifo_errors)},
- {"rx_missed_errors", IXGBE_STAT(net_stats.rx_missed_errors)},
- {"tx_aborted_errors", IXGBE_STAT(net_stats.tx_aborted_errors)},
- {"tx_carrier_errors", IXGBE_STAT(net_stats.tx_carrier_errors)},
- {"tx_fifo_errors", IXGBE_STAT(net_stats.tx_fifo_errors)},
- {"tx_heartbeat_errors", IXGBE_STAT(net_stats.tx_heartbeat_errors)},
+ {"rx_fifo_errors", IXGBE_NETDEV_STAT(stats.rx_fifo_errors)},
+ {"rx_missed_errors", IXGBE_NETDEV_STAT(stats.rx_missed_errors)},
+ {"tx_aborted_errors", IXGBE_NETDEV_STAT(stats.tx_aborted_errors)},
+ {"tx_carrier_errors", IXGBE_NETDEV_STAT(stats.tx_carrier_errors)},
+ {"tx_fifo_errors", IXGBE_NETDEV_STAT(stats.tx_fifo_errors)},
+ {"tx_heartbeat_errors", IXGBE_NETDEV_STAT(stats.tx_heartbeat_errors)},
{"tx_timeout_count", IXGBE_STAT(tx_timeout_count)},
{"tx_restart_queue", IXGBE_STAT(restart_queue)},
{"rx_long_length_errors", IXGBE_STAT(stats.roc)},
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index cbb143c..c91d50e 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -372,8 +372,8 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
tx_ring->total_packets += total_packets;
tx_ring->stats.packets += total_packets;
tx_ring->stats.bytes += total_bytes;
- adapter->net_stats.tx_bytes += total_bytes;
- adapter->net_stats.tx_packets += total_packets;
+ netdev->stats.tx_bytes += total_bytes;
+ netdev->stats.tx_packets += total_packets;
return (count < tx_ring->work_limit);
}
@@ -709,6 +709,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
int *work_done, int work_to_do)
{
struct ixgbe_adapter *adapter = q_vector->adapter;
+ struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
@@ -880,8 +881,8 @@ next_desc:
rx_ring->total_packets += total_rx_packets;
rx_ring->total_bytes += total_rx_bytes;
- adapter->net_stats.rx_bytes += total_rx_bytes;
- adapter->net_stats.rx_packets += total_rx_packets;
+ netdev->stats.rx_bytes += total_rx_bytes;
+ netdev->stats.rx_packets += total_rx_packets;
return cleaned;
}
@@ -4403,6 +4404,7 @@ static void ixgbe_shutdown(struct pci_dev *pdev)
**/
void ixgbe_update_stats(struct ixgbe_adapter *adapter)
{
+ struct net_device *netdev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw;
u64 total_mpc = 0;
u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
@@ -4522,15 +4524,15 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
adapter->stats.bptc += IXGBE_READ_REG(hw, IXGBE_BPTC);
/* Fill out the OS statistics structure */
- adapter->net_stats.multicast = adapter->stats.mprc;
+ netdev->stats.multicast = adapter->stats.mprc;
/* Rx Errors */
- adapter->net_stats.rx_errors = adapter->stats.crcerrs +
+ netdev->stats.rx_errors = adapter->stats.crcerrs +
adapter->stats.rlec;
- adapter->net_stats.rx_dropped = 0;
- adapter->net_stats.rx_length_errors = adapter->stats.rlec;
- adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
- adapter->net_stats.rx_missed_errors = total_mpc;
+ netdev->stats.rx_dropped = 0;
+ netdev->stats.rx_length_errors = adapter->stats.rlec;
+ netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
+ netdev->stats.rx_missed_errors = total_mpc;
}
/**
@@ -5300,10 +5302,8 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
**/
static struct net_device_stats *ixgbe_get_stats(struct net_device *netdev)
{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
/* only return the current stats */
- return &adapter->net_stats;
+ return &netdev->stats;
}
/**
--
1.6.0.4
^ permalink raw reply related
* [PATCH net-next-2.6] igb: Use the instance of net_device_stats from net_device.
From: Ajit Khaparde @ 2009-10-07 12:42 UTC (permalink / raw)
To: davem, netdev
Since net_device has an instance of net_device_stats,
we can remove the instance of this from the adapter structure.
Signed-off-by: Ajit Khaparde <ajitk@serverengines.com>
---
drivers/net/igb/igb.h | 1 -
drivers/net/igb/igb_ethtool.c | 20 +++++++++++---------
drivers/net/igb/igb_main.c | 39 +++++++++++++++++++--------------------
3 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 7126fea..b805b1c 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -256,7 +256,6 @@ struct igb_adapter {
struct net_device *netdev;
struct napi_struct napi;
struct pci_dev *pdev;
- struct net_device_stats net_stats;
struct cyclecounter cycles;
struct timecounter clock;
struct timecompare compare;
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index d004c35..d46c321 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -45,6 +45,8 @@ struct igb_stats {
#define IGB_STAT(m) FIELD_SIZEOF(struct igb_adapter, m), \
offsetof(struct igb_adapter, m)
+#define IGB_NETDEV_STAT(m) FIELD_SIZEOF(struct net_device, m), \
+ offsetof(struct net_device, m)
static const struct igb_stats igb_gstrings_stats[] = {
{ "rx_packets", IGB_STAT(stats.gprc) },
{ "tx_packets", IGB_STAT(stats.gptc) },
@@ -54,22 +56,22 @@ static const struct igb_stats igb_gstrings_stats[] = {
{ "tx_broadcast", IGB_STAT(stats.bptc) },
{ "rx_multicast", IGB_STAT(stats.mprc) },
{ "tx_multicast", IGB_STAT(stats.mptc) },
- { "rx_errors", IGB_STAT(net_stats.rx_errors) },
- { "tx_errors", IGB_STAT(net_stats.tx_errors) },
- { "tx_dropped", IGB_STAT(net_stats.tx_dropped) },
+ { "rx_errors", IGB_NETDEV_STAT(stats.rx_errors) },
+ { "tx_errors", IGB_NETDEV_STAT(stats.tx_errors) },
+ { "tx_dropped", IGB_NETDEV_STAT(stats.tx_dropped) },
{ "multicast", IGB_STAT(stats.mprc) },
{ "collisions", IGB_STAT(stats.colc) },
- { "rx_length_errors", IGB_STAT(net_stats.rx_length_errors) },
- { "rx_over_errors", IGB_STAT(net_stats.rx_over_errors) },
+ { "rx_length_errors", IGB_NETDEV_STAT(stats.rx_length_errors) },
+ { "rx_over_errors", IGB_NETDEV_STAT(stats.rx_over_errors) },
{ "rx_crc_errors", IGB_STAT(stats.crcerrs) },
- { "rx_frame_errors", IGB_STAT(net_stats.rx_frame_errors) },
+ { "rx_frame_errors", IGB_NETDEV_STAT(stats.rx_frame_errors) },
{ "rx_no_buffer_count", IGB_STAT(stats.rnbc) },
- { "rx_queue_drop_packet_count", IGB_STAT(net_stats.rx_fifo_errors) },
+ { "rx_queue_drop_packet_count", IGB_NETDEV_STAT(stats.rx_fifo_errors) },
{ "rx_missed_errors", IGB_STAT(stats.mpc) },
{ "tx_aborted_errors", IGB_STAT(stats.ecol) },
{ "tx_carrier_errors", IGB_STAT(stats.tncrs) },
- { "tx_fifo_errors", IGB_STAT(net_stats.tx_fifo_errors) },
- { "tx_heartbeat_errors", IGB_STAT(net_stats.tx_heartbeat_errors) },
+ { "tx_fifo_errors", IGB_NETDEV_STAT(stats.tx_fifo_errors) },
+ { "tx_heartbeat_errors", IGB_NETDEV_STAT(stats.tx_heartbeat_errors) },
{ "tx_window_errors", IGB_STAT(stats.latecol) },
{ "tx_abort_late_coll", IGB_STAT(stats.latecol) },
{ "tx_deferred_ok", IGB_STAT(stats.dc) },
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 83c0837..428d504 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3534,10 +3534,8 @@ static void igb_reset_task(struct work_struct *work)
**/
static struct net_device_stats *igb_get_stats(struct net_device *netdev)
{
- struct igb_adapter *adapter = netdev_priv(netdev);
-
/* only return the current stats */
- return &adapter->net_stats;
+ return &netdev->stats;
}
/**
@@ -3623,6 +3621,7 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu)
void igb_update_stats(struct igb_adapter *adapter)
{
+ struct net_device *netdev = adapter->netdev;
struct e1000_hw *hw = &adapter->hw;
struct pci_dev *pdev = adapter->pdev;
u16 phy_tmp;
@@ -3712,8 +3711,8 @@ void igb_update_stats(struct igb_adapter *adapter)
adapter->stats.icrxdmtc += rd32(E1000_ICRXDMTC);
/* Fill out the OS statistics structure */
- adapter->net_stats.multicast = adapter->stats.mprc;
- adapter->net_stats.collisions = adapter->stats.colc;
+ netdev->stats.multicast = adapter->stats.mprc;
+ netdev->stats.collisions = adapter->stats.colc;
/* Rx Errors */
@@ -3734,7 +3733,7 @@ void igb_update_stats(struct igb_adapter *adapter)
adapter->rx_ring[i].rx_stats.drops += rqdpc_tmp;
rqdpc_total += adapter->rx_ring[i].rx_stats.drops;
}
- adapter->net_stats.rx_fifo_errors = rqdpc_total;
+ netdev->stats.rx_fifo_errors = rqdpc_total;
}
/* Note RNBC (Receive No Buffers Count) is an not an exact
@@ -3742,26 +3741,26 @@ void igb_update_stats(struct igb_adapter *adapter)
* one of the reason for saving it in rx_fifo_errors, as its
* potentially not a true drop.
*/
- adapter->net_stats.rx_fifo_errors += adapter->stats.rnbc;
+ netdev->stats.rx_fifo_errors += adapter->stats.rnbc;
/* RLEC on some newer hardware can be incorrect so build
* our own version based on RUC and ROC */
- adapter->net_stats.rx_errors = adapter->stats.rxerrc +
+ netdev->stats.rx_errors = adapter->stats.rxerrc +
adapter->stats.crcerrs + adapter->stats.algnerrc +
adapter->stats.ruc + adapter->stats.roc +
adapter->stats.cexterr;
- adapter->net_stats.rx_length_errors = adapter->stats.ruc +
+ netdev->stats.rx_length_errors = adapter->stats.ruc +
adapter->stats.roc;
- adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
- adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
- adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
+ netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
+ netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
+ netdev->stats.rx_missed_errors = adapter->stats.mpc;
/* Tx Errors */
- adapter->net_stats.tx_errors = adapter->stats.ecol +
+ netdev->stats.tx_errors = adapter->stats.ecol +
adapter->stats.latecol;
- adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
- adapter->net_stats.tx_window_errors = adapter->stats.latecol;
- adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
+ netdev->stats.tx_aborted_errors = adapter->stats.ecol;
+ netdev->stats.tx_window_errors = adapter->stats.latecol;
+ netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
/* Tx Dropped needs to be maintained elsewhere */
@@ -4640,8 +4639,8 @@ static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
tx_ring->total_packets += total_packets;
tx_ring->tx_stats.bytes += total_bytes;
tx_ring->tx_stats.packets += total_packets;
- adapter->net_stats.tx_bytes += total_bytes;
- adapter->net_stats.tx_packets += total_packets;
+ netdev->stats.tx_bytes += total_bytes;
+ netdev->stats.tx_packets += total_packets;
return (count < tx_ring->count);
}
@@ -4884,8 +4883,8 @@ next_desc:
rx_ring->total_bytes += total_bytes;
rx_ring->rx_stats.packets += total_packets;
rx_ring->rx_stats.bytes += total_bytes;
- adapter->net_stats.rx_bytes += total_bytes;
- adapter->net_stats.rx_packets += total_packets;
+ netdev->stats.rx_bytes += total_bytes;
+ netdev->stats.rx_packets += total_packets;
return cleaned;
}
--
1.6.0.4
^ permalink raw reply related
* [PATCH net-next-2.6] e1000: Use the instance of net_device_stats from net_device.
From: Ajit Khaparde @ 2009-10-07 12:42 UTC (permalink / raw)
To: davem, netdev
Since net_device has an instance of net_device_stats,
we can remove the instance of this from the adapter structure.
Signed-off-by: Ajit Khaparde <ajitk@serverengines.com>
---
drivers/net/e1000/e1000.h | 1 -
drivers/net/e1000/e1000_ethtool.c | 12 ++++++----
drivers/net/e1000/e1000_main.c | 41 ++++++++++++++++++-------------------
3 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 42e2b7e..a566528 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -302,7 +302,6 @@ struct e1000_adapter {
/* OS defined structs */
struct net_device *netdev;
struct pci_dev *pdev;
- struct net_device_stats net_stats;
/* structs defined in e1000_hw.h */
struct e1000_hw hw;
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 490b2b7..e25b339 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -39,6 +39,8 @@ struct e1000_stats {
#define E1000_STAT(m) FIELD_SIZEOF(struct e1000_adapter, m), \
offsetof(struct e1000_adapter, m)
+#define E1000_NETDEV_STAT(m) FIELD_SIZEOF(struct net_device, m), \
+ offsetof(struct net_device, m)
static const struct e1000_stats e1000_gstrings_stats[] = {
{ "rx_packets", E1000_STAT(stats.gprc) },
{ "tx_packets", E1000_STAT(stats.gptc) },
@@ -50,19 +52,19 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
{ "tx_multicast", E1000_STAT(stats.mptc) },
{ "rx_errors", E1000_STAT(stats.rxerrc) },
{ "tx_errors", E1000_STAT(stats.txerrc) },
- { "tx_dropped", E1000_STAT(net_stats.tx_dropped) },
+ { "tx_dropped", E1000_NETDEV_STAT(stats.tx_dropped) },
{ "multicast", E1000_STAT(stats.mprc) },
{ "collisions", E1000_STAT(stats.colc) },
{ "rx_length_errors", E1000_STAT(stats.rlerrc) },
- { "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) },
+ { "rx_over_errors", E1000_NETDEV_STAT(stats.rx_over_errors) },
{ "rx_crc_errors", E1000_STAT(stats.crcerrs) },
- { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) },
+ { "rx_frame_errors", E1000_NETDEV_STAT(stats.rx_frame_errors) },
{ "rx_no_buffer_count", E1000_STAT(stats.rnbc) },
{ "rx_missed_errors", E1000_STAT(stats.mpc) },
{ "tx_aborted_errors", E1000_STAT(stats.ecol) },
{ "tx_carrier_errors", E1000_STAT(stats.tncrs) },
- { "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) },
- { "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) },
+ { "tx_fifo_errors", E1000_NETDEV_STAT(stats.tx_fifo_errors) },
+ { "tx_heartbeat_errors", E1000_NETDEV_STAT(stats.tx_heartbeat_errors) },
{ "tx_window_errors", E1000_STAT(stats.latecol) },
{ "tx_abort_late_coll", E1000_STAT(stats.latecol) },
{ "tx_deferred_ok", E1000_STAT(stats.dc) },
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index bcd192c..6a61414 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3101,10 +3101,8 @@ static void e1000_reset_task(struct work_struct *work)
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
{
- struct e1000_adapter *adapter = netdev_priv(netdev);
-
/* only return the current stats */
- return &adapter->net_stats;
+ return &netdev->stats;
}
/**
@@ -3196,6 +3194,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
void e1000_update_stats(struct e1000_adapter *adapter)
{
+ struct net_device *netdev = adapter->netdev;
struct e1000_hw *hw = &adapter->hw;
struct pci_dev *pdev = adapter->pdev;
unsigned long flags;
@@ -3288,32 +3287,32 @@ void e1000_update_stats(struct e1000_adapter *adapter)
}
/* Fill out the OS statistics structure */
- adapter->net_stats.multicast = adapter->stats.mprc;
- adapter->net_stats.collisions = adapter->stats.colc;
+ netdev->stats.multicast = adapter->stats.mprc;
+ netdev->stats.collisions = adapter->stats.colc;
/* Rx Errors */
/* RLEC on some newer hardware can be incorrect so build
* our own version based on RUC and ROC */
- adapter->net_stats.rx_errors = adapter->stats.rxerrc +
+ netdev->stats.rx_errors = adapter->stats.rxerrc +
adapter->stats.crcerrs + adapter->stats.algnerrc +
adapter->stats.ruc + adapter->stats.roc +
adapter->stats.cexterr;
adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
- adapter->net_stats.rx_length_errors = adapter->stats.rlerrc;
- adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
- adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
- adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
+ netdev->stats.rx_length_errors = adapter->stats.rlerrc;
+ netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
+ netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
+ netdev->stats.rx_missed_errors = adapter->stats.mpc;
/* Tx Errors */
adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
- adapter->net_stats.tx_errors = adapter->stats.txerrc;
- adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
- adapter->net_stats.tx_window_errors = adapter->stats.latecol;
- adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
+ netdev->stats.tx_errors = adapter->stats.txerrc;
+ netdev->stats.tx_aborted_errors = adapter->stats.ecol;
+ netdev->stats.tx_window_errors = adapter->stats.latecol;
+ netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
if (hw->bad_tx_carr_stats_fd &&
adapter->link_duplex == FULL_DUPLEX) {
- adapter->net_stats.tx_carrier_errors = 0;
+ netdev->stats.tx_carrier_errors = 0;
adapter->stats.tncrs = 0;
}
@@ -3514,8 +3513,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
}
adapter->total_tx_bytes += total_tx_bytes;
adapter->total_tx_packets += total_tx_packets;
- adapter->net_stats.tx_bytes += total_tx_bytes;
- adapter->net_stats.tx_packets += total_tx_packets;
+ netdev->stats.tx_bytes += total_tx_bytes;
+ netdev->stats.tx_packets += total_tx_packets;
return (count < tx_ring->count);
}
@@ -3767,8 +3766,8 @@ next_desc:
adapter->total_rx_packets += total_rx_packets;
adapter->total_rx_bytes += total_rx_bytes;
- adapter->net_stats.rx_bytes += total_rx_bytes;
- adapter->net_stats.rx_packets += total_rx_packets;
+ netdev->stats.rx_bytes += total_rx_bytes;
+ netdev->stats.rx_packets += total_rx_packets;
return cleaned;
}
@@ -3916,8 +3915,8 @@ next_desc:
adapter->total_rx_packets += total_rx_packets;
adapter->total_rx_bytes += total_rx_bytes;
- adapter->net_stats.rx_bytes += total_rx_bytes;
- adapter->net_stats.rx_packets += total_rx_packets;
+ netdev->stats.rx_bytes += total_rx_bytes;
+ netdev->stats.rx_packets += total_rx_packets;
return cleaned;
}
--
1.6.0.4
^ permalink raw reply related
* [PATCH net-next-2.6 0/8] Get rid of net_device_stats from adapter.
From: Ajit Khaparde @ 2009-10-07 12:41 UTC (permalink / raw)
To: davem, netdev
Since net_device already has an instance of net_device stats,
its not necessary for the drivers to maintain their own copy
in their private adapter structure.
This patch series takes care of this for some of the drivers.
I have compiled them all in my setup.
And not all of them have been tested. :-)
Thanks
-Ajit
^ permalink raw reply
* netconf notes and materials
From: David Miller @ 2009-10-07 11:47 UTC (permalink / raw)
To: netdev
Just a note that all of the available notes and slide etc.
materials are available for netconf2009 at:
http://vger.kernel.org/netconf2009.html
Enjoy.
^ permalink raw reply
* [GIT]: Networking
From: David Miller @ 2009-10-07 11:19 UTC (permalink / raw)
To: torvalds; +Cc: akpm, netdev, linux-kernel
1) Device ID additions for IXGBE, and some CIS additions for
pcmcia networking devices.
2) Two pktgen fixes from Eric Dumazet. Packet delays regressed
in this merge window and the multiqueue support doesn't handle
specifying exactly one specific queue to use properly.
3) Kill libc5 crap from linux/socket.h, that just makes it impossible
to include sys/socket.h after it in userland apps. From Ben Hutchings.
4) e1000e regression fix, limitation on jumbo frames was applied to
wrong chip IDs. From Alexander Duyck.
5) get_wireless_stats() executes get stats operations in a different
context than it normally would, they need to be able to sleep.
So when getting stats from sysfs, use rtnl mutex instead of
dev_base_lock. From Johannes Berg.
6) be2net flash operation submission, ethtool TX checksumming,
multicast frame accounting, and macro definition fixes from Ajit
Khaparde.
7) tg3 PHY library locking was bolixed, fixed by Matt Carlson.
8) Improperly paren'd unlikely() statement in netxen driver, fix from
Roel Kluin.
9) qlge bug fixes from Ron Mercer
10) Fix from Stephen Hemminger for arp_notify, it can crash with
a NULL pointer if there are no IPV4 addresses attached to the
interface at notification time. With help from Eric Dumazet.
11) ethoc bug fixes from Thomas Chou
12) Deal with the backlog of ISDN bug fixes from Tilman Schmidt,
Karsten hasn't been respinsive for 2 or 3 weeks so I'm handling
ISDN stuff starting now until he can find time again.
13) pasemi_mac can oops on a NULL pointer on ethtool get-settings
calls with some PHY types, fix from Valentine Barshak.
14) au1000_eth tests wrong bits for RX errors, fix from Roel Kluin.
Please pull, thanks a lot!
The following changes since commit 0eca52a92735f43462165efe00a7e394345fb38e:
Linus Torvalds (1):
Merge git://git.kernel.org/.../davem/ide-2.6
are available in the git repository at:
master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.git master
Ajit Khaparde (4):
be2net: Fix a bug in preparation of mcc wrb which was causing flash operation to fail
be2net: Bug Fix while accounting of multicast frames during netdev stats update
be2net: Fix a typo in be_cmds.h
be2net: Bug fix to properly update ethtool tx-checksumming after ethtool -K <ifname> tx off
Alexander Duyck (1):
e1000e: swap max hw supported frame size between 82574 and 82583
Ben Hutchings (1):
net: Support inclusion of <linux/socket.h> before <sys/socket.h>
Don Skidmore (2):
ixgbe: add support for 82599 Combined Backplane
ixgbe: add support for 82599 based X520 10G Dual KX4 Mezz card
Eric Dumazet (2):
pktgen: Fix multiqueue handling
pktgen: restore nanosec delays
Johannes Berg (1):
wext: let get_wireless_stats() sleep
John W. Linville (1):
rndis_host: support ETHTOOL_GPERMADDR
Ken Kawasaki (1):
pcnet_cs: add cis of National Semicondoctor's multifunction pcmcia card
Matt Carlson (1):
tg3: Fix phylib locking strategy
Neil Horman (1):
add maintainer for network drop monitor kernel service
Roel Kluin (1):
netxen: Fix Unlikely(x) > y
Ron Mercer (3):
qlge: Fix some bit definitions for reset register.
qlge: Fix queueing of firmware handler in ISR.
qlge: Fix lock/mutex warnings.
Stephen Boyd (1):
connector: Fix incompatible pointer type warning
Stephen Hemminger (1):
ipv4: arp_notify address list bug
Thomas Chou (5):
ethoc: fix typo to compute number of tx descriptors
ethoc: fix buffer address mapping
ethoc: align received packet to make IP header at word boundary
ethoc: use system memory as buffer
ethoc: limit the number of buffers to 128
Tilman Schmidt (12):
Documentation: expand isdn/INTERFACE.CAPI document
isdn: accept CAPI Informational Info values as success
isdn: avoid races in capidrv
isdn: make capidrv module parameter "debugmode" writeable
gigaset: fix reject/hangup handling
gigaset: linearize skb
gigaset: handle isoc frame errors more gracefully
gigaset: announce if built with debugging
gigaset: fix device ERROR response handling
gigaset: improve error recovery
gigaset: correct debugging output selection
gigaset: add kerneldoc comments
Valentine Barshak (1):
pasemi_mac: ethtool get settings fix
roel kluin (1):
au1000_eth: Duplicate test of RX_OVERLEN bit in update_rx_stats()
Documentation/isdn/INTERFACE.CAPI | 83 +++++++++++++++++----
Documentation/networking/pktgen.txt | 8 ++
MAINTAINERS | 7 ++
drivers/connector/cn_proc.c | 3 +-
drivers/isdn/capi/capi.c | 2 +-
drivers/isdn/capi/capidrv.c | 27 ++++---
drivers/isdn/gigaset/asyncdata.c | 28 +++++---
drivers/isdn/gigaset/bas-gigaset.c | 87 +++++++++++++---------
drivers/isdn/gigaset/common.c | 134 ++++++++++++++++++++++++++++------
drivers/isdn/gigaset/ev-layer.c | 30 +++++---
drivers/isdn/gigaset/i4l.c | 23 ++++++
drivers/isdn/gigaset/interface.c | 9 ++
drivers/isdn/gigaset/isocdata.c | 30 ++++---
drivers/net/au1000_eth.c | 4 +-
drivers/net/benet/be_cmds.c | 1 -
drivers/net/benet/be_cmds.h | 2 +-
drivers/net/benet/be_ethtool.c | 2 +-
drivers/net/benet/be_main.c | 6 +-
drivers/net/e1000e/82571.c | 4 +-
drivers/net/ethoc.c | 81 ++++++++++++++-------
drivers/net/ixgbe/ixgbe_82599.c | 2 +
drivers/net/ixgbe/ixgbe_main.c | 4 +
drivers/net/ixgbe/ixgbe_type.h | 2 +
drivers/net/netxen/netxen_nic_main.c | 2 +-
drivers/net/pasemi_mac_ethtool.c | 3 +
drivers/net/pcmcia/pcnet_cs.c | 10 +-
drivers/net/qlge/qlge.h | 8 +-
drivers/net/qlge/qlge_ethtool.c | 2 -
drivers/net/qlge/qlge_main.c | 18 +---
drivers/net/qlge/qlge_mpi.c | 12 ++-
drivers/net/tg3.c | 41 ++++-------
drivers/net/tg3.h | 1 -
drivers/net/usb/rndis_host.c | 1 +
drivers/serial/serial_cs.c | 12 ++--
firmware/Makefile | 7 +-
firmware/WHENCE | 5 +
firmware/cis/COMpad2.cis.ihex | 11 +++
firmware/cis/COMpad4.cis.ihex | 9 ++
firmware/cis/DP83903.cis.ihex | 14 ++++
firmware/cis/NE2K.cis.ihex | 8 ++
firmware/cis/tamarack.cis.ihex | 10 +++
include/linux/socket.h | 21 +-----
net/core/net-sysfs.c | 4 +-
net/core/pktgen.c | 4 +-
net/ipv4/devinet.c | 16 +++--
45 files changed, 545 insertions(+), 253 deletions(-)
create mode 100644 firmware/cis/COMpad2.cis.ihex
create mode 100644 firmware/cis/COMpad4.cis.ihex
create mode 100644 firmware/cis/DP83903.cis.ihex
create mode 100644 firmware/cis/NE2K.cis.ihex
create mode 100644 firmware/cis/tamarack.cis.ihex
^ permalink raw reply
* [PATCH] x25: bit and/or confusion in x25_ioctl()?
From: Roel Kluin @ 2009-10-07 10:59 UTC (permalink / raw)
To: linux-x25, netdev, David S. Miller, Andrew Morton
Looking at commit ebc3f64b864f it appears that this was intended
and not the original, equivalent to `if (facilities.reverse & ~0x81)'.
In x25_parse_facilities() that patch changed how facilities->reverse
was set. No other bits were set than 0x80 and/or 0x01.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
This is correct isn't it?
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 7fa9c7a..ca4dc28 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -1363,7 +1363,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
facilities.throughput > 0xDD)
break;
if (facilities.reverse &&
- (facilities.reverse | 0x81)!= 0x81)
+ (facilities.reverse & 0x81) != 0x81)
break;
x25->facilities = facilities;
rc = 0;
^ permalink raw reply related
* Re: [net-next-2.6 PATCH V2] can: add TI CAN (HECC) driver
From: David Miller @ 2009-10-07 10:49 UTC (permalink / raw)
To: wg; +Cc: anantgole, netdev, socketcan-core, linux-arm-kernel
In-Reply-To: <20091007.034425.54165326.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Date: Wed, 07 Oct 2009 03:44:25 -0700 (PDT)
> From: Wolfgang Grandegger <wg@grandegger.com>
> Date: Wed, 07 Oct 2009 09:15:24 +0200
>
>> Anant Gole wrote:
>>> TI HECC (High End CAN Controller) module is found on many TI devices. It
>>> has 32 hardware mailboxes with full implementation of CAN protocol 2.0B
>>> with bus speeds up to 1Mbps. Specifications of the module are available
>>> on TI web <http://www.ti.com>
>>>
>>> Signed-off-by: Anant Gole <anantgole@ti.com>
>>
>> Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
>>
>> Thanks for your contribution.
>
> Applied, thanks everyone.
Actually I have to revert this.
You have to add restrictions to the Kconfig entry for this
driver so that it only builds where the necessary interfaces
exist.
Otherwise it will fail to link on non-ARM platforms because
they lack the clk_*() functions this driver uses.
^ permalink raw reply
* Re: [PATCH net-next-2.6] udp: dynamically size hash tables at boot time
From: David Miller @ 2009-10-07 10:47 UTC (permalink / raw)
To: eric.dumazet; +Cc: rick.jones2, netdev
In-Reply-To: <4ACC6F87.1050306@gmail.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 07 Oct 2009 12:37:59 +0200
> David Miller a écrit :
>>
>> That's incredible that it's been that low for so long :-)
>>
>> Bug please, dynamically size this thing, maybe with a cap of say 64K
>> to start with. If you don't have time for it I'll take care of this.
>
> Here we are.
...
> [PATCH] udp: dynamically size hash tables at boot time
Looks good to me.
I'll let this sit for at least a day to get some review from
others.
Thanks!
^ permalink raw reply
* Re: [PATCH] au1000_eth: Duplicate test of RX_OVERLEN bit in update_rx_stats()
From: David Miller @ 2009-10-07 10:44 UTC (permalink / raw)
To: manuel.lauss; +Cc: roel.kluin, netdev, akpm, manuel.lauss
In-Reply-To: <f861ec6f0910061253g28743e80r2db772aa7101f098@mail.gmail.com>
From: Manuel Lauss <manuel.lauss@googlemail.com>
Date: Tue, 6 Oct 2009 21:53:50 +0200
> On Tue, Oct 6, 2009 at 9:54 PM, Roel Kluin <roel.kluin@gmail.com> wrote:
>> in update_rx_stats() the RX_OVERLEN bit is set twice, replace it by RX_RUNT.
>> in au1000_rx() the RX_MISSED_FRAME bit was tested a few lines earlier already
>>
>> Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
...
>
> Yeah, looks right.
>
> Acked-by: Manuel Lauss <manuel.lauss@gmail.com>
Applied, thanks.
^ permalink raw reply
* Re: [net-next-2.6 PATCH V2] can: add TI CAN (HECC) driver
From: David Miller @ 2009-10-07 10:44 UTC (permalink / raw)
To: wg; +Cc: anantgole, netdev, socketcan-core, linux-arm-kernel
In-Reply-To: <4ACC400C.2020708@grandegger.com>
From: Wolfgang Grandegger <wg@grandegger.com>
Date: Wed, 07 Oct 2009 09:15:24 +0200
> Anant Gole wrote:
>> TI HECC (High End CAN Controller) module is found on many TI devices. It
>> has 32 hardware mailboxes with full implementation of CAN protocol 2.0B
>> with bus speeds up to 1Mbps. Specifications of the module are available
>> on TI web <http://www.ti.com>
>>
>> Signed-off-by: Anant Gole <anantgole@ti.com>
>
> Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
>
> Thanks for your contribution.
Applied, thanks everyone.
^ permalink raw reply
* Re: [PATCH] pasemi_mac: ethtool get settings fix
From: David Miller @ 2009-10-07 10:43 UTC (permalink / raw)
To: olof; +Cc: linuxppc-dev, jgarzik, netdev
In-Reply-To: <20091006161054.GB29195@lixom.net>
From: Olof Johansson <olof@lixom.net>
Date: Tue, 6 Oct 2009 11:10:54 -0500
> Weird, I see my address in the to: line but I never got a copy in my inbox.
>
> On Mon, Oct 05, 2009 at 05:27:56PM +0400, Valentine Barshak wrote:
>> Not all pasemi mac interfaces can have a phy attached.
>> For example, XAUI has no phy and phydev is NULL for it.
>> In this case ethtool get settings causes kernel crash.
>> Fix it by returning -EOPNOTSUPP if there's no PHY attached.
>>
>> Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com>
>
> Acked-by: Olof Johansson <olof@lixom.net>
Applied to net-2.6, thanks!
^ permalink raw reply
* Re: [PATCH] add maintainer for network drop monitor kernel service
From: David Miller @ 2009-10-07 10:42 UTC (permalink / raw)
To: nhorman; +Cc: netdev
In-Reply-To: <20091005135653.GB2898@localhost.localdomain>
From: Neil Horman <nhorman@tuxdriver.com>
Date: Mon, 5 Oct 2009 09:56:55 -0400
> I was getting ribbed about this earlier, so I figured I'd make it official. Add
> myself as the maintainer of the drop monitor bits, so people don't just gripe at
> Dave when it breaks (I'm sure it will never break, but just in case :) ).
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Applied.
^ permalink raw reply
* Re: [PATCH] netxen: Fix Unlikely(x) > y
From: David Miller @ 2009-10-07 10:42 UTC (permalink / raw)
To: dhananjay.phadke; +Cc: roel.kluin, netdev, akpm
In-Reply-To: <7608421F3572AB4292BB2532AE89D5658B0B6A7C12@AVEXMB1.qlogic.org>
From: Dhananjay Phadke <dhananjay.phadke@qlogic.com>
Date: Tue, 6 Oct 2009 22:34:39 -0700
> Oh sure, that was a typo. Thanks for catching it.
>
> Acked-by: Dhananjay Phadke <dhananjay@netxen.com>
Applied, thanks everyone.
^ permalink raw reply
* Re: [PATCH] ethoc: limit the number of buffers to 128
From: David Miller @ 2009-10-07 10:42 UTC (permalink / raw)
To: thomas; +Cc: netdev, thierry.reding, nios2-dev, linux-kernel
In-Reply-To: <1254835525-2529-1-git-send-email-thomas@wytron.com.tw>
From: Thomas Chou <thomas@wytron.com.tw>
Date: Tue, 6 Oct 2009 21:25:25 +0800
> Only 128 buffer descriptors are supported in the core. Limit the
> number in case we have more memory.
>
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
Applied.
^ permalink raw reply
* Re: [PATCH 4/4] ethoc: use system memory as buffer
From: David Miller @ 2009-10-07 10:42 UTC (permalink / raw)
To: thomas; +Cc: netdev
In-Reply-To: <1254735200-2718-4-git-send-email-thomas@wytron.com.tw>
From: Thomas Chou <thomas@wytron.com.tw>
Date: Mon, 5 Oct 2009 17:33:20 +0800
> This patch enabled the ethoc to allocate system memory as buffer
> when there is no dedicated buffer memory.
>
> Some hardware designs may not have dedicated buffer memory such as
> on chip or off chip SRAM. In this case, only one memory resource is
> supplied in the platform data instead of two. Then a DMA buffer can
> be allocated from system memory and used for the transfer.
>
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
Applied.
^ permalink raw reply
* Re: [PATCH 2/4] ethoc: fix buffer address mapping
From: David Miller @ 2009-10-07 10:42 UTC (permalink / raw)
To: thomas; +Cc: netdev
In-Reply-To: <1254735200-2718-2-git-send-email-thomas@wytron.com.tw>
From: Thomas Chou <thomas@wytron.com.tw>
Date: Mon, 5 Oct 2009 17:33:18 +0800
> The pointer address in buffer descriptors is physical address. The
> pointer that processor used to access packet is virtual address.
>
> Though the higher bits of pointer address used by the MAC may be
> truncated to zero in special case, it is not always true in larger
> designs.
>
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
Applied.
^ permalink raw reply
* Re: [PATCH 3/4] ethoc: align received packet to make IP header at word boundary
From: David Miller @ 2009-10-07 10:42 UTC (permalink / raw)
To: thomas; +Cc: netdev
In-Reply-To: <1254735200-2718-3-git-send-email-thomas@wytron.com.tw>
From: Thomas Chou <thomas@wytron.com.tw>
Date: Mon, 5 Oct 2009 17:33:19 +0800
> The packet buffer is allocated at 4 bytes boundary, but the IP header
> length and version bits is located at byte 14. These bit fields access
> as 32 bits word and caused exception on processors that do not support
> unaligned access.
>
> The patch adds 2 bytes offset to make the bit fields word aligned.
>
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
Applied.
^ permalink raw reply
* Re: [PATCH 1/4] ethoc: fix typo to compute number of tx descriptors
From: David Miller @ 2009-10-07 10:41 UTC (permalink / raw)
To: thomas; +Cc: netdev
In-Reply-To: <1254735200-2718-1-git-send-email-thomas@wytron.com.tw>
From: Thomas Chou <thomas@wytron.com.tw>
Date: Mon, 5 Oct 2009 17:33:17 +0800
> It should be max() instead of min(). Use 1/4 of available
> descriptors for tx, and there should be at least 2 tx
> descriptors.
>
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
Applied.
^ permalink raw reply
* Re: [PATCH net-2.6 V2] tg3: Fix phylib locking strategy
From: David Miller @ 2009-10-07 10:41 UTC (permalink / raw)
To: mcarlson; +Cc: felix, netdev, mchan, andy
In-Reply-To: <1254801692.18507@xw6200>
From: "Matt Carlson" <mcarlson@broadcom.com>
Date: Mon, 5 Oct 2009 20:55:29 -0700
> O.K. Here is the latest version. Felix, can you verify your problem
> is solved with this patch?
>
> ---
>
> Felix Radensky noted that chip resets were generating stack trace dumps.
> This is because the driver is attempting to acquire the mdio bus mutex
> while holding the tp->lock spinlock. The fix is to change the code such
> that every phy access takes the tp->lock spinlock instead.
>
> Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
I'm going to apply this now to net-2.6, let me know if there are
any updates after testing.
^ permalink raw reply
* Re: r8169 chips on some Intel D945GSEJT boards fail to work after PXE boot
From: Simon Farnsworth @ 2009-10-07 10:39 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev
In-Reply-To: <20091006215601.GA10692@electric-eye.fr.zoreil.com>
Francois Romieu wrote:
> Francois Romieu <romieu@fr.zoreil.com> :
> [...]
>> @@ -2200,6 +3075,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>> tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
>> if (!tp->pcie_cap && netif_msg_probe(tp))
>> dev_info(&pdev->dev, "no PCI Express capability\n");
>> + else {
>> + pci_write_config_word(pdev, tp->pcie_cap + PCI_EXP_DEVSTA,
>> + PCI_EXP_DEVSTA_CED | PCI_EXP_DEVSTA_NFED |
>> + PCI_EXP_DEVSTA_FED | PCI_EXP_DEVSTA_URD);
>> + }
>>
>> RTL_W16(IntrMask, 0x0000);
>>
>
> Can you check if this part of the patch is required to fix
> your issue ?
>
> I'd rather avoid including it under the 8168d support banner
> if it is not needed.
>
I can confirm that I don't need that hunk.
--
Simon Farnsworth
^ permalink raw reply
* [PATCH net-next-2.6] udp: dynamically size hash tables at boot time
From: Eric Dumazet @ 2009-10-07 10:37 UTC (permalink / raw)
To: David Miller; +Cc: rick.jones2, netdev
In-Reply-To: <20091006.222935.231081303.davem@davemloft.net>
David Miller a écrit :
>
> That's incredible that it's been that low for so long :-)
>
> Bug please, dynamically size this thing, maybe with a cap of say 64K
> to start with. If you don't have time for it I'll take care of this.
Here we are.
Thank you
[PATCH] udp: dynamically size hash tables at boot time
UDP_HTABLE_SIZE was initialy defined to 128, which is a bit small for several setups.
4000 active UDP sockets -> 32 sockets per chain in average. An incoming frame
has to lookup all sockets to find best match, so long chains hurt latency.
Instead of a fixed size hash table that cant be perfect for every needs,
let UDP stack choose its table size at boot time like tcp/ip route,
using alloc_large_system_hash() helper
Add an optional boot parameter, uhash_entries=x so that an admin can force a size
between 256 and 65536 if needed, like thash_entries and rhash_entries.
dmesg logs two new lines :
[ 0.647039] UDP hash table entries: 512 (order: 0, 4096 bytes)
[ 0.647099] UDP Lite hash table entries: 512 (order: 0, 4096 bytes)
Maximal size on 64bit arches would be 65536 slots, ie 1 MBytes for non debugging spinlocks.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
Documentation/kernel-parameters.txt | 3
include/linux/udp.h | 6 -
include/net/udp.h | 13 ++-
net/ipv4/udp.c | 91 ++++++++++++++++++--------
net/ipv4/udplite.c | 4 -
net/ipv6/udp.c | 6 -
6 files changed, 87 insertions(+), 36 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 6fa7292..02df20b 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2589,6 +2589,9 @@ and is between 256 and 4096 characters. It is defined in the file
uart6850= [HW,OSS]
Format: <io>,<irq>
+ uhash_entries= [KNL,NET]
+ Set number of hash buckets for UDP/UDP-Lite connections
+
uhci-hcd.ignore_oc=
[USB] Ignore overcurrent events (default N).
Some badly-designed motherboards generate lots of
diff --git a/include/linux/udp.h b/include/linux/udp.h
index 0cf5c4c..832361e 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -45,11 +45,11 @@ static inline struct udphdr *udp_hdr(const struct sk_buff *skb)
return (struct udphdr *)skb_transport_header(skb);
}
-#define UDP_HTABLE_SIZE 128
+#define UDP_HTABLE_SIZE_MIN (CONFIG_BASE_SMALL ? 128 : 256)
-static inline int udp_hashfn(struct net *net, const unsigned num)
+static inline int udp_hashfn(struct net *net, unsigned num, unsigned mask)
{
- return (num + net_hash_mix(net)) & (UDP_HTABLE_SIZE - 1);
+ return (num + net_hash_mix(net)) & mask;
}
struct udp_sock {
diff --git a/include/net/udp.h b/include/net/udp.h
index f98abd2..22aa2e7 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -54,12 +54,19 @@ struct udp_hslot {
struct hlist_nulls_head head;
spinlock_t lock;
} __attribute__((aligned(2 * sizeof(long))));
+
struct udp_table {
- struct udp_hslot hash[UDP_HTABLE_SIZE];
+ struct udp_hslot *hash;
+ unsigned int mask;
+ unsigned int log;
};
extern struct udp_table udp_table;
-extern void udp_table_init(struct udp_table *);
-
+extern void udp_table_init(struct udp_table *, const char *);
+static inline struct udp_hslot *udp_hashslot(struct udp_table *table,
+ struct net *net, unsigned num)
+{
+ return &table->hash[udp_hashfn(net, num, table->mask)];
+}
/* Note: this must match 'valbool' in sock_setsockopt */
#define UDP_CSUM_NOXMIT 1
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 6ec6a8a..194bcdc 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -106,7 +106,7 @@
#include <net/xfrm.h>
#include "udp_impl.h"
-struct udp_table udp_table;
+struct udp_table udp_table __read_mostly;
EXPORT_SYMBOL(udp_table);
int sysctl_udp_mem[3] __read_mostly;
@@ -121,14 +121,16 @@ EXPORT_SYMBOL(sysctl_udp_wmem_min);
atomic_t udp_memory_allocated;
EXPORT_SYMBOL(udp_memory_allocated);
-#define PORTS_PER_CHAIN (65536 / UDP_HTABLE_SIZE)
+#define MAX_UDP_PORTS 65536
+#define PORTS_PER_CHAIN (MAX_UDP_PORTS / UDP_HTABLE_SIZE_MIN)
static int udp_lib_lport_inuse(struct net *net, __u16 num,
const struct udp_hslot *hslot,
unsigned long *bitmap,
struct sock *sk,
int (*saddr_comp)(const struct sock *sk1,
- const struct sock *sk2))
+ const struct sock *sk2),
+ unsigned int log)
{
struct sock *sk2;
struct hlist_nulls_node *node;
@@ -142,8 +144,7 @@ static int udp_lib_lport_inuse(struct net *net, __u16 num,
|| sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
(*saddr_comp)(sk, sk2)) {
if (bitmap)
- __set_bit(sk2->sk_hash / UDP_HTABLE_SIZE,
- bitmap);
+ __set_bit(sk2->sk_hash >> log, bitmap);
else
return 1;
}
@@ -180,13 +181,15 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
/*
* force rand to be an odd multiple of UDP_HTABLE_SIZE
*/
- rand = (rand | 1) * UDP_HTABLE_SIZE;
- for (last = first + UDP_HTABLE_SIZE; first != last; first++) {
- hslot = &udptable->hash[udp_hashfn(net, first)];
+ rand = (rand | 1) * (udptable->mask + 1);
+ for (last = first + udptable->mask + 1;
+ first != last;
+ first++) {
+ hslot = udp_hashslot(udptable, net, first);
bitmap_zero(bitmap, PORTS_PER_CHAIN);
spin_lock_bh(&hslot->lock);
udp_lib_lport_inuse(net, snum, hslot, bitmap, sk,
- saddr_comp);
+ saddr_comp, udptable->log);
snum = first;
/*
@@ -196,7 +199,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
*/
do {
if (low <= snum && snum <= high &&
- !test_bit(snum / UDP_HTABLE_SIZE, bitmap))
+ !test_bit(snum >> udptable->log, bitmap))
goto found;
snum += rand;
} while (snum != first);
@@ -204,9 +207,10 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
}
goto fail;
} else {
- hslot = &udptable->hash[udp_hashfn(net, snum)];
+ hslot = udp_hashslot(udptable, net, snum);
spin_lock_bh(&hslot->lock);
- if (udp_lib_lport_inuse(net, snum, hslot, NULL, sk, saddr_comp))
+ if (udp_lib_lport_inuse(net, snum, hslot, NULL, sk,
+ saddr_comp, 0))
goto fail_unlock;
}
found:
@@ -283,7 +287,7 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
struct sock *sk, *result;
struct hlist_nulls_node *node;
unsigned short hnum = ntohs(dport);
- unsigned int hash = udp_hashfn(net, hnum);
+ unsigned int hash = udp_hashfn(net, hnum, udptable->mask);
struct udp_hslot *hslot = &udptable->hash[hash];
int score, badness;
@@ -1013,8 +1017,8 @@ void udp_lib_unhash(struct sock *sk)
{
if (sk_hashed(sk)) {
struct udp_table *udptable = sk->sk_prot->h.udp_table;
- unsigned int hash = udp_hashfn(sock_net(sk), sk->sk_hash);
- struct udp_hslot *hslot = &udptable->hash[hash];
+ struct udp_hslot *hslot = udp_hashslot(udptable, sock_net(sk),
+ sk->sk_hash);
spin_lock_bh(&hslot->lock);
if (sk_nulls_del_node_init_rcu(sk)) {
@@ -1169,7 +1173,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
struct udp_table *udptable)
{
struct sock *sk;
- struct udp_hslot *hslot = &udptable->hash[udp_hashfn(net, ntohs(uh->dest))];
+ struct udp_hslot *hslot = udp_hashslot(udptable, net, ntohs(uh->dest));
int dif;
spin_lock(&hslot->lock);
@@ -1609,9 +1613,14 @@ static struct sock *udp_get_first(struct seq_file *seq, int start)
struct udp_iter_state *state = seq->private;
struct net *net = seq_file_net(seq);
- for (state->bucket = start; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
+ for (state->bucket = start; state->bucket <= state->udp_table->mask;
+ ++state->bucket) {
struct hlist_nulls_node *node;
struct udp_hslot *hslot = &state->udp_table->hash[state->bucket];
+
+ if (hlist_nulls_empty(&hslot->head))
+ continue;
+
spin_lock_bh(&hslot->lock);
sk_nulls_for_each(sk, node, &hslot->head) {
if (!net_eq(sock_net(sk), net))
@@ -1636,7 +1645,7 @@ static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk)
} while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != state->family));
if (!sk) {
- if (state->bucket < UDP_HTABLE_SIZE)
+ if (state->bucket <= state->udp_table->mask)
spin_unlock_bh(&state->udp_table->hash[state->bucket].lock);
return udp_get_first(seq, state->bucket + 1);
}
@@ -1656,7 +1665,7 @@ static struct sock *udp_get_idx(struct seq_file *seq, loff_t pos)
static void *udp_seq_start(struct seq_file *seq, loff_t *pos)
{
struct udp_iter_state *state = seq->private;
- state->bucket = UDP_HTABLE_SIZE;
+ state->bucket = MAX_UDP_PORTS;
return *pos ? udp_get_idx(seq, *pos-1) : SEQ_START_TOKEN;
}
@@ -1678,7 +1687,7 @@ static void udp_seq_stop(struct seq_file *seq, void *v)
{
struct udp_iter_state *state = seq->private;
- if (state->bucket < UDP_HTABLE_SIZE)
+ if (state->bucket <= state->udp_table->mask)
spin_unlock_bh(&state->udp_table->hash[state->bucket].lock);
}
@@ -1738,7 +1747,7 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f,
__u16 destp = ntohs(inet->dport);
__u16 srcp = ntohs(inet->sport);
- seq_printf(f, "%4d: %08X:%04X %08X:%04X"
+ seq_printf(f, "%5d: %08X:%04X %08X:%04X"
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d%n",
bucket, src, srcp, dest, destp, sp->sk_state,
sk_wmem_alloc_get(sp),
@@ -1804,11 +1813,43 @@ void udp4_proc_exit(void)
}
#endif /* CONFIG_PROC_FS */
-void __init udp_table_init(struct udp_table *table)
+static __initdata unsigned long uhash_entries;
+static int __init set_uhash_entries(char *str)
{
- int i;
+ if (!str)
+ return 0;
+ uhash_entries = simple_strtoul(str, &str, 0);
+ if (uhash_entries && uhash_entries < UDP_HTABLE_SIZE_MIN)
+ uhash_entries = UDP_HTABLE_SIZE_MIN;
+ return 1;
+}
+__setup("uhash_entries=", set_uhash_entries);
- for (i = 0; i < UDP_HTABLE_SIZE; i++) {
+void __init udp_table_init(struct udp_table *table, const char *name)
+{
+ unsigned int i;
+
+ if (!CONFIG_BASE_SMALL)
+ table->hash = alloc_large_system_hash(name,
+ sizeof(struct udp_hslot),
+ uhash_entries,
+ 21, /* one slot per 2 MB */
+ 0,
+ &table->log,
+ &table->mask,
+ 64 * 1024);
+ /*
+ * Make sure hash table has the minimum size
+ */
+ if (CONFIG_BASE_SMALL || table->mask < UDP_HTABLE_SIZE_MIN - 1) {
+ table->hash = kmalloc(UDP_HTABLE_SIZE_MIN *
+ sizeof(struct udp_hslot), GFP_KERNEL);
+ if (!table->hash)
+ panic(name);
+ table->log = ilog2(UDP_HTABLE_SIZE_MIN);
+ table->mask = UDP_HTABLE_SIZE_MIN - 1;
+ }
+ for (i = 0; i <= table->mask; i++) {
INIT_HLIST_NULLS_HEAD(&table->hash[i].head, i);
spin_lock_init(&table->hash[i].lock);
}
@@ -1818,7 +1859,7 @@ void __init udp_init(void)
{
unsigned long nr_pages, limit;
- udp_table_init(&udp_table);
+ udp_table_init(&udp_table, "UDP");
/* Set the pressure threshold up by the same strategy of TCP. It is a
* fraction of global memory that is up to 1/2 at 256 MB, decreasing
* toward zero with the amount of memory, with a floor of 128 pages.
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
index 95248d7..a495ca8 100644
--- a/net/ipv4/udplite.c
+++ b/net/ipv4/udplite.c
@@ -12,7 +12,7 @@
*/
#include "udp_impl.h"
-struct udp_table udplite_table;
+struct udp_table udplite_table __read_mostly;
EXPORT_SYMBOL(udplite_table);
static int udplite_rcv(struct sk_buff *skb)
@@ -110,7 +110,7 @@ static inline int udplite4_proc_init(void)
void __init udplite4_register(void)
{
- udp_table_init(&udplite_table);
+ udp_table_init(&udplite_table, "UDP-Lite");
if (proto_register(&udplite_prot, 1))
goto out_register_err;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 3a60f12..d42f503 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -132,7 +132,7 @@ static struct sock *__udp6_lib_lookup(struct net *net,
struct sock *sk, *result;
struct hlist_nulls_node *node;
unsigned short hnum = ntohs(dport);
- unsigned int hash = udp_hashfn(net, hnum);
+ unsigned int hash = udp_hashfn(net, hnum, udptable->mask);
struct udp_hslot *hslot = &udptable->hash[hash];
int score, badness;
@@ -452,7 +452,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
{
struct sock *sk, *sk2;
const struct udphdr *uh = udp_hdr(skb);
- struct udp_hslot *hslot = &udptable->hash[udp_hashfn(net, ntohs(uh->dest))];
+ struct udp_hslot *hslot = udp_hashslot(udptable, net, ntohs(uh->dest));
int dif;
spin_lock(&hslot->lock);
@@ -1195,7 +1195,7 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket
destp = ntohs(inet->dport);
srcp = ntohs(inet->sport);
seq_printf(seq,
- "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
+ "%5d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
"%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n",
bucket,
src->s6_addr32[0], src->s6_addr32[1],
^ permalink raw reply related
* Re: [PATCH] Add sk_mark route lookup support for IPv4 listening sockets, and for IPv4 multicast forwarding
From: David Miller @ 2009-10-07 10:19 UTC (permalink / raw)
To: atis; +Cc: netdev, panther, eric.dumazet, brian.haley, zenczykowski
In-Reply-To: <200910051646.34770.atis@mikrotik.com>
From: Atis Elsts <atis@mikrotik.com>
Date: Mon, 5 Oct 2009 16:46:34 +0300
> @@ -1238,6 +1238,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
>
> if (vif->flags&VIFF_TUNNEL) {
> struct flowi fl = { .oif = vif->link,
> + .mark = skb->mark,
> .nl_u = { .ip4_u =
> { .daddr = vif->remote,
> .saddr = vif->local,
I'm not so sure if this is right.
I understand what you're trying to do, inherit the socket's
mark when it goes over a multicast tunnel.
But I'm not so sure that's what we want to do, semantically.
Could you split out these skb->mark cases into a seperate
patch? The parts that only use sk->mark are fine and I
would like to apply a patch from you which just does that
while we discuss the skb->mark case.
Thanks.
^ permalink raw reply
* Re: [PATCH] ipv4: arp_notify address list bug
From: David Miller @ 2009-10-07 10:18 UTC (permalink / raw)
To: eric.dumazet; +Cc: hannes, shemminger, netdev
In-Reply-To: <4ACAD393.5080909@gmail.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 06 Oct 2009 07:20:19 +0200
> From: Stephen Hemminger <shemminger@vyatta.com>
>
> This fixes a bug with arp_notify.
>
> If arp_notify is enabled, kernel will crash if address is changed
> and no IP address is assigned.
> http://bugzilla.kernel.org/show_bug.cgi?id=14330
>
> Reported-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Applied, thanks everyone.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox