forked from rubenslte/android_kernel_samsung_msm8226
Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d879fdb682 | ||
|
|
df5b8022a3 | ||
|
|
937e219392 | ||
|
|
0dc07e5e86 | ||
|
|
e402d6690a | ||
|
|
c0f11335f0 | ||
|
|
6458fae8c6 | ||
|
|
d2b407c6e9 | ||
|
|
d98e94aa33 | ||
|
|
c53f9fa5e6 | ||
|
|
6e4ace5791 | ||
|
|
a940318aa8 | ||
|
|
12c87d10ae | ||
|
|
383b34a07e | ||
|
|
abfa69dbc8 | ||
|
|
c1a13a08bf | ||
|
|
9cb6b68302 | ||
|
|
78f01d8157 | ||
|
|
1244a55f8f | ||
|
|
6cc9064350 |
@@ -130,17 +130,6 @@ somaxconn - INTEGER
|
||||
Defaults to 128. See also tcp_max_syn_backlog for additional tuning
|
||||
for TCP sockets.
|
||||
|
||||
tcp_abc - INTEGER
|
||||
Controls Appropriate Byte Count (ABC) defined in RFC3465.
|
||||
ABC is a way of increasing congestion window (cwnd) more slowly
|
||||
in response to partial acknowledgments.
|
||||
Possible values are:
|
||||
0 increase cwnd once per acknowledgment (no ABC)
|
||||
1 increase cwnd once per acknowledgment of full sized segment
|
||||
2 allow increase cwnd by two if acknowledgment is
|
||||
of two segments to compensate for delayed acknowledgments.
|
||||
Default: 0 (off)
|
||||
|
||||
tcp_abort_on_overflow - BOOLEAN
|
||||
If listening service is too slow to accept new connections,
|
||||
reset them. Default state is FALSE. It means that if overflow
|
||||
@@ -477,6 +466,15 @@ tcp_syn_retries - INTEGER
|
||||
tcp_timestamps - BOOLEAN
|
||||
Enable timestamps as defined in RFC1323.
|
||||
|
||||
tcp_min_tso_segs - INTEGER
|
||||
Minimal number of segments per TSO frame.
|
||||
Since linux-3.12, TCP does an automatic sizing of TSO frames,
|
||||
depending on flow rate, instead of filling 64Kbytes packets.
|
||||
For specific usages, it's possible to force TCP to build big
|
||||
TSO frames. Note that TCP stack might split too big TSO packets
|
||||
if available window is too small.
|
||||
Default: 2
|
||||
|
||||
tcp_tso_win_divisor - INTEGER
|
||||
This allows control over what percentage of the congestion window
|
||||
can be consumed by a single TSO frame.
|
||||
@@ -557,6 +555,17 @@ tcp_challenge_ack_limit - INTEGER
|
||||
in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks)
|
||||
Default: 100
|
||||
|
||||
tcp_limit_output_bytes - INTEGER
|
||||
Controls TCP Small Queue limit per tcp socket.
|
||||
TCP bulk sender tends to increase packets in flight until it
|
||||
gets losses notifications. With SNDBUF autotuning, this can
|
||||
result in a large amount of packets queued in qdisc/device
|
||||
on the local machine, hurting latency of other flows, for
|
||||
typical pfifo_fast qdiscs.
|
||||
tcp_limit_output_bytes limits the number of bytes on qdisc
|
||||
or device to reduce artificial RTT/cwnd and reduce bufferbloat.
|
||||
Default: 131072
|
||||
|
||||
UDP variables:
|
||||
|
||||
udp_mem - vector of 3 INTEGERs: min, pressure, max
|
||||
|
||||
@@ -76,6 +76,8 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 43
|
||||
|
||||
#define SO_MAX_PACING_RATE 44
|
||||
|
||||
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
|
||||
* have to define SOCK_NONBLOCK to a different value here.
|
||||
*/
|
||||
|
||||
@@ -69,4 +69,6 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 43
|
||||
|
||||
#define SO_MAX_PACING_RATE 44
|
||||
|
||||
#endif /* _ASM_SOCKET_H */
|
||||
|
||||
@@ -69,4 +69,6 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 43
|
||||
|
||||
#define SO_MAX_PACING_RATE 44
|
||||
|
||||
#endif /* __ASM_AVR32_SOCKET_H */
|
||||
|
||||
@@ -71,6 +71,8 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 43
|
||||
|
||||
#define SO_MAX_PACING_RATE 44
|
||||
|
||||
#endif /* _ASM_SOCKET_H */
|
||||
|
||||
|
||||
|
||||
@@ -69,5 +69,7 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 43
|
||||
|
||||
#define SO_MAX_PACING_RATE 44
|
||||
|
||||
#endif /* _ASM_SOCKET_H */
|
||||
|
||||
|
||||
@@ -69,4 +69,6 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 43
|
||||
|
||||
#define SO_MAX_PACING_RATE 44
|
||||
|
||||
#endif /* _ASM_SOCKET_H */
|
||||
|
||||
@@ -78,4 +78,6 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 43
|
||||
|
||||
#define SO_MAX_PACING_RATE 44
|
||||
|
||||
#endif /* _ASM_IA64_SOCKET_H */
|
||||
|
||||
@@ -69,4 +69,6 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 43
|
||||
|
||||
#define SO_MAX_PACING_RATE 44
|
||||
|
||||
#endif /* _ASM_M32R_SOCKET_H */
|
||||
|
||||
@@ -69,4 +69,6 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 43
|
||||
|
||||
#define SO_MAX_PACING_RATE 44
|
||||
|
||||
#endif /* _ASM_SOCKET_H */
|
||||
|
||||
@@ -89,6 +89,8 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 43
|
||||
|
||||
#define SO_MAX_PACING_RATE 44
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/** sock_type - Socket types
|
||||
|
||||
@@ -69,4 +69,6 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 43
|
||||
|
||||
#define SO_MAX_PACING_RATE 44
|
||||
|
||||
#endif /* _ASM_SOCKET_H */
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 0x4024
|
||||
|
||||
#define SO_MAX_PACING_RATE 0x4025
|
||||
|
||||
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
|
||||
* have to define SOCK_NONBLOCK to a different value here.
|
||||
|
||||
@@ -76,4 +76,6 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 43
|
||||
|
||||
#define SO_MAX_PACING_RATE 44
|
||||
|
||||
#endif /* _ASM_POWERPC_SOCKET_H */
|
||||
|
||||
@@ -77,4 +77,6 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 43
|
||||
|
||||
#define SO_MAX_PACING_RATE 44
|
||||
|
||||
#endif /* _ASM_SOCKET_H */
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 0x0027
|
||||
|
||||
#define SO_MAX_PACING_RATE 0x0028
|
||||
|
||||
/* Security levels - as per NRL IPv6 - don't actually do anything */
|
||||
#define SO_SECURITY_AUTHENTICATION 0x5001
|
||||
|
||||
@@ -80,4 +80,6 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 43
|
||||
|
||||
#define SO_MAX_PACING_RATE 47
|
||||
|
||||
#endif /* _XTENSA_SOCKET_H */
|
||||
|
||||
@@ -100,10 +100,16 @@ static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
|
||||
static int dummy_dev_init(struct net_device *dev)
|
||||
{
|
||||
int i;
|
||||
dev->dstats = alloc_percpu(struct pcpu_dstats);
|
||||
if (!dev->dstats)
|
||||
return -ENOMEM;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct pcpu_dstats *dstats;
|
||||
dstats = per_cpu_ptr(dev->dstats, i);
|
||||
u64_stats_init(&dstats->syncp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -347,10 +347,10 @@ be_get_ethtool_stats(struct net_device *netdev,
|
||||
struct be_rx_stats *stats = rx_stats(rxo);
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&stats->sync);
|
||||
start = u64_stats_fetch_begin_irq(&stats->sync);
|
||||
data[base] = stats->rx_bytes;
|
||||
data[base + 1] = stats->rx_pkts;
|
||||
} while (u64_stats_fetch_retry_bh(&stats->sync, start));
|
||||
} while (u64_stats_fetch_retry_irq(&stats->sync, start));
|
||||
|
||||
for (i = 2; i < ETHTOOL_RXSTATS_NUM; i++) {
|
||||
p = (u8 *)stats + et_rx_stats[i].offset;
|
||||
@@ -363,19 +363,19 @@ be_get_ethtool_stats(struct net_device *netdev,
|
||||
struct be_tx_stats *stats = tx_stats(txo);
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&stats->sync_compl);
|
||||
start = u64_stats_fetch_begin_irq(&stats->sync_compl);
|
||||
data[base] = stats->tx_compl;
|
||||
} while (u64_stats_fetch_retry_bh(&stats->sync_compl, start));
|
||||
} while (u64_stats_fetch_retry_irq(&stats->sync_compl, start));
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&stats->sync);
|
||||
start = u64_stats_fetch_begin_irq(&stats->sync);
|
||||
for (i = 1; i < ETHTOOL_TXSTATS_NUM; i++) {
|
||||
p = (u8 *)stats + et_tx_stats[i].offset;
|
||||
data[base + i] =
|
||||
(et_tx_stats[i].size == sizeof(u64)) ?
|
||||
*(u64 *)p : *(u32 *)p;
|
||||
}
|
||||
} while (u64_stats_fetch_retry_bh(&stats->sync, start));
|
||||
} while (u64_stats_fetch_retry_irq(&stats->sync, start));
|
||||
base += ETHTOOL_TXSTATS_NUM;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,10 +445,10 @@ static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev,
|
||||
for_all_rx_queues(adapter, rxo, i) {
|
||||
const struct be_rx_stats *rx_stats = rx_stats(rxo);
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&rx_stats->sync);
|
||||
start = u64_stats_fetch_begin_irq(&rx_stats->sync);
|
||||
pkts = rx_stats(rxo)->rx_pkts;
|
||||
bytes = rx_stats(rxo)->rx_bytes;
|
||||
} while (u64_stats_fetch_retry_bh(&rx_stats->sync, start));
|
||||
} while (u64_stats_fetch_retry_irq(&rx_stats->sync, start));
|
||||
stats->rx_packets += pkts;
|
||||
stats->rx_bytes += bytes;
|
||||
stats->multicast += rx_stats(rxo)->rx_mcast_pkts;
|
||||
@@ -459,10 +459,10 @@ static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev,
|
||||
for_all_tx_queues(adapter, txo, i) {
|
||||
const struct be_tx_stats *tx_stats = tx_stats(txo);
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&tx_stats->sync);
|
||||
start = u64_stats_fetch_begin_irq(&tx_stats->sync);
|
||||
pkts = tx_stats(txo)->tx_pkts;
|
||||
bytes = tx_stats(txo)->tx_bytes;
|
||||
} while (u64_stats_fetch_retry_bh(&tx_stats->sync, start));
|
||||
} while (u64_stats_fetch_retry_irq(&tx_stats->sync, start));
|
||||
stats->tx_packets += pkts;
|
||||
stats->tx_bytes += bytes;
|
||||
}
|
||||
@@ -1086,9 +1086,9 @@ static void be_eqd_update(struct be_adapter *adapter, struct be_eq_obj *eqo)
|
||||
return;
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&stats->sync);
|
||||
start = u64_stats_fetch_begin_irq(&stats->sync);
|
||||
pkts = stats->rx_pkts;
|
||||
} while (u64_stats_fetch_retry_bh(&stats->sync, start));
|
||||
} while (u64_stats_fetch_retry_irq(&stats->sync, start));
|
||||
|
||||
stats->rx_pps = (unsigned long)(pkts - stats->rx_pkts_prev) / (delta / HZ);
|
||||
stats->rx_pkts_prev = pkts;
|
||||
@@ -1823,6 +1823,9 @@ static int be_tx_cqs_create(struct be_adapter *adapter)
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
u64_stats_init(&txo->stats.sync);
|
||||
u64_stats_init(&txo->stats.sync_compl);
|
||||
|
||||
/* If num_evt_qs is less than num_tx_qs, then more than
|
||||
* one txq share an eq
|
||||
*/
|
||||
@@ -1888,6 +1891,7 @@ static int be_rx_cqs_create(struct be_adapter *adapter)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
u64_stats_init(&rxo->stats.sync);
|
||||
eq = &adapter->eq_obj[i % adapter->num_evt_qs].q;
|
||||
rc = be_cmd_cq_create(adapter, cq, eq, false, 3);
|
||||
if (rc)
|
||||
|
||||
@@ -2094,15 +2094,15 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
|
||||
|
||||
ring = adapter->tx_ring[j];
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&ring->tx_syncp);
|
||||
start = u64_stats_fetch_begin_irq(&ring->tx_syncp);
|
||||
data[i] = ring->tx_stats.packets;
|
||||
data[i+1] = ring->tx_stats.bytes;
|
||||
data[i+2] = ring->tx_stats.restart_queue;
|
||||
} while (u64_stats_fetch_retry_bh(&ring->tx_syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start));
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&ring->tx_syncp2);
|
||||
start = u64_stats_fetch_begin_irq(&ring->tx_syncp2);
|
||||
restart2 = ring->tx_stats.restart_queue2;
|
||||
} while (u64_stats_fetch_retry_bh(&ring->tx_syncp2, start));
|
||||
} while (u64_stats_fetch_retry_irq(&ring->tx_syncp2, start));
|
||||
data[i+2] += restart2;
|
||||
|
||||
i += IGB_TX_QUEUE_STATS_LEN;
|
||||
@@ -2110,13 +2110,13 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
|
||||
for (j = 0; j < adapter->num_rx_queues; j++) {
|
||||
ring = adapter->rx_ring[j];
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&ring->rx_syncp);
|
||||
start = u64_stats_fetch_begin_irq(&ring->rx_syncp);
|
||||
data[i] = ring->rx_stats.packets;
|
||||
data[i+1] = ring->rx_stats.bytes;
|
||||
data[i+2] = ring->rx_stats.drops;
|
||||
data[i+3] = ring->rx_stats.csum_err;
|
||||
data[i+4] = ring->rx_stats.alloc_failed;
|
||||
} while (u64_stats_fetch_retry_bh(&ring->rx_syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start));
|
||||
i += IGB_RX_QUEUE_STATS_LEN;
|
||||
}
|
||||
spin_unlock(&adapter->stats64_lock);
|
||||
|
||||
@@ -728,6 +728,8 @@ static int igb_alloc_queues(struct igb_adapter *adapter)
|
||||
/* For 82575, context index must be unique per ring. */
|
||||
if (adapter->hw.mac.type == e1000_82575)
|
||||
set_bit(IGB_RING_FLAG_TX_CTX_IDX, &ring->flags);
|
||||
u64_stats_init(&ring->tx_syncp);
|
||||
u64_stats_init(&ring->tx_syncp2);
|
||||
adapter->tx_ring[i] = ring;
|
||||
}
|
||||
/* Restore the adapter's original node */
|
||||
@@ -759,6 +761,7 @@ static int igb_alloc_queues(struct igb_adapter *adapter)
|
||||
if (adapter->hw.mac.type == e1000_i350)
|
||||
set_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &ring->flags);
|
||||
|
||||
u64_stats_init(&ring->rx_syncp);
|
||||
adapter->rx_ring[i] = ring;
|
||||
}
|
||||
/* Restore the adapter's original node */
|
||||
@@ -4658,10 +4661,10 @@ void igb_update_stats(struct igb_adapter *adapter,
|
||||
}
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&ring->rx_syncp);
|
||||
start = u64_stats_fetch_begin_irq(&ring->rx_syncp);
|
||||
_bytes = ring->rx_stats.bytes;
|
||||
_packets = ring->rx_stats.packets;
|
||||
} while (u64_stats_fetch_retry_bh(&ring->rx_syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start));
|
||||
bytes += _bytes;
|
||||
packets += _packets;
|
||||
}
|
||||
@@ -4674,10 +4677,10 @@ void igb_update_stats(struct igb_adapter *adapter,
|
||||
for (i = 0; i < adapter->num_tx_queues; i++) {
|
||||
struct igb_ring *ring = adapter->tx_ring[i];
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&ring->tx_syncp);
|
||||
start = u64_stats_fetch_begin_irq(&ring->tx_syncp);
|
||||
_bytes = ring->tx_stats.bytes;
|
||||
_packets = ring->tx_stats.packets;
|
||||
} while (u64_stats_fetch_retry_bh(&ring->tx_syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start));
|
||||
bytes += _bytes;
|
||||
packets += _packets;
|
||||
}
|
||||
|
||||
@@ -1093,10 +1093,10 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
|
||||
}
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&ring->syncp);
|
||||
start = u64_stats_fetch_begin_irq(&ring->syncp);
|
||||
data[i] = ring->stats.packets;
|
||||
data[i+1] = ring->stats.bytes;
|
||||
} while (u64_stats_fetch_retry_bh(&ring->syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&ring->syncp, start));
|
||||
i += 2;
|
||||
}
|
||||
for (j = 0; j < IXGBE_NUM_RX_QUEUES; j++) {
|
||||
@@ -1109,10 +1109,10 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
|
||||
}
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&ring->syncp);
|
||||
start = u64_stats_fetch_begin_irq(&ring->syncp);
|
||||
data[i] = ring->stats.packets;
|
||||
data[i+1] = ring->stats.bytes;
|
||||
} while (u64_stats_fetch_retry_bh(&ring->syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&ring->syncp, start));
|
||||
i += 2;
|
||||
}
|
||||
|
||||
|
||||
@@ -4497,6 +4497,8 @@ int ixgbe_setup_tx_resources(struct ixgbe_ring *tx_ring)
|
||||
if (!tx_ring->tx_buffer_info)
|
||||
goto err;
|
||||
|
||||
u64_stats_init(&tx_ring->syncp);
|
||||
|
||||
/* round up to nearest 4K */
|
||||
tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc);
|
||||
tx_ring->size = ALIGN(tx_ring->size, 4096);
|
||||
@@ -4573,6 +4575,8 @@ int ixgbe_setup_rx_resources(struct ixgbe_ring *rx_ring)
|
||||
if (!rx_ring->rx_buffer_info)
|
||||
goto err;
|
||||
|
||||
u64_stats_init(&rx_ring->syncp);
|
||||
|
||||
/* Round up to nearest 4K */
|
||||
rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc);
|
||||
rx_ring->size = ALIGN(rx_ring->size, 4096);
|
||||
@@ -6480,10 +6484,10 @@ static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev,
|
||||
|
||||
if (ring) {
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&ring->syncp);
|
||||
start = u64_stats_fetch_begin_irq(&ring->syncp);
|
||||
packets = ring->stats.packets;
|
||||
bytes = ring->stats.bytes;
|
||||
} while (u64_stats_fetch_retry_bh(&ring->syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&ring->syncp, start));
|
||||
stats->rx_packets += packets;
|
||||
stats->rx_bytes += bytes;
|
||||
}
|
||||
@@ -6496,10 +6500,10 @@ static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev,
|
||||
|
||||
if (ring) {
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&ring->syncp);
|
||||
start = u64_stats_fetch_begin_irq(&ring->syncp);
|
||||
packets = ring->stats.packets;
|
||||
bytes = ring->stats.bytes;
|
||||
} while (u64_stats_fetch_retry_bh(&ring->syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&ring->syncp, start));
|
||||
stats->tx_packets += packets;
|
||||
stats->tx_bytes += bytes;
|
||||
}
|
||||
|
||||
@@ -3231,10 +3231,10 @@ static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev,
|
||||
for (i = 0; i < adapter->num_rx_queues; i++) {
|
||||
ring = &adapter->rx_ring[i];
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&ring->syncp);
|
||||
start = u64_stats_fetch_begin_irq(&ring->syncp);
|
||||
bytes = ring->total_bytes;
|
||||
packets = ring->total_packets;
|
||||
} while (u64_stats_fetch_retry_bh(&ring->syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&ring->syncp, start));
|
||||
stats->rx_bytes += bytes;
|
||||
stats->rx_packets += packets;
|
||||
}
|
||||
@@ -3242,10 +3242,10 @@ static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev,
|
||||
for (i = 0; i < adapter->num_tx_queues; i++) {
|
||||
ring = &adapter->tx_ring[i];
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&ring->syncp);
|
||||
start = u64_stats_fetch_begin_irq(&ring->syncp);
|
||||
bytes = ring->total_bytes;
|
||||
packets = ring->total_packets;
|
||||
} while (u64_stats_fetch_retry_bh(&ring->syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&ring->syncp, start));
|
||||
stats->tx_bytes += bytes;
|
||||
stats->tx_packets += packets;
|
||||
}
|
||||
|
||||
@@ -3892,19 +3892,19 @@ static struct rtnl_link_stats64 *sky2_get_stats(struct net_device *dev,
|
||||
u64 _bytes, _packets;
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&sky2->rx_stats.syncp);
|
||||
start = u64_stats_fetch_begin_irq(&sky2->rx_stats.syncp);
|
||||
_bytes = sky2->rx_stats.bytes;
|
||||
_packets = sky2->rx_stats.packets;
|
||||
} while (u64_stats_fetch_retry_bh(&sky2->rx_stats.syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&sky2->rx_stats.syncp, start));
|
||||
|
||||
stats->rx_packets = _packets;
|
||||
stats->rx_bytes = _bytes;
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&sky2->tx_stats.syncp);
|
||||
start = u64_stats_fetch_begin_irq(&sky2->tx_stats.syncp);
|
||||
_bytes = sky2->tx_stats.bytes;
|
||||
_packets = sky2->tx_stats.packets;
|
||||
} while (u64_stats_fetch_retry_bh(&sky2->tx_stats.syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&sky2->tx_stats.syncp, start));
|
||||
|
||||
stats->tx_packets = _packets;
|
||||
stats->tx_bytes = _bytes;
|
||||
@@ -4750,6 +4750,9 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
|
||||
sky2->hw = hw;
|
||||
sky2->msg_enable = netif_msg_init(debug, default_msg);
|
||||
|
||||
u64_stats_init(&sky2->tx_stats.syncp);
|
||||
u64_stats_init(&sky2->rx_stats.syncp);
|
||||
|
||||
/* Auto speed and flow control */
|
||||
sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE;
|
||||
if (hw->chip_id != CHIP_ID_YUKON_XL)
|
||||
|
||||
@@ -2073,6 +2073,10 @@ static int vxge_open_vpaths(struct vxgedev *vdev)
|
||||
vdev->config.tx_steering_type;
|
||||
vpath->fifo.ndev = vdev->ndev;
|
||||
vpath->fifo.pdev = vdev->pdev;
|
||||
|
||||
u64_stats_init(&vpath->fifo.stats.syncp);
|
||||
u64_stats_init(&vpath->ring.stats.syncp);
|
||||
|
||||
if (vdev->config.tx_steering_type)
|
||||
vpath->fifo.txq =
|
||||
netdev_get_tx_queue(vdev->ndev, i);
|
||||
|
||||
@@ -1755,19 +1755,19 @@ nv_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *storage)
|
||||
|
||||
/* software stats */
|
||||
do {
|
||||
syncp_start = u64_stats_fetch_begin_bh(&np->swstats_rx_syncp);
|
||||
syncp_start = u64_stats_fetch_begin_irq(&np->swstats_rx_syncp);
|
||||
storage->rx_packets = np->stat_rx_packets;
|
||||
storage->rx_bytes = np->stat_rx_bytes;
|
||||
storage->rx_dropped = np->stat_rx_dropped;
|
||||
storage->rx_missed_errors = np->stat_rx_missed_errors;
|
||||
} while (u64_stats_fetch_retry_bh(&np->swstats_rx_syncp, syncp_start));
|
||||
} while (u64_stats_fetch_retry_irq(&np->swstats_rx_syncp, syncp_start));
|
||||
|
||||
do {
|
||||
syncp_start = u64_stats_fetch_begin_bh(&np->swstats_tx_syncp);
|
||||
syncp_start = u64_stats_fetch_begin_irq(&np->swstats_tx_syncp);
|
||||
storage->tx_packets = np->stat_tx_packets;
|
||||
storage->tx_bytes = np->stat_tx_bytes;
|
||||
storage->tx_dropped = np->stat_tx_dropped;
|
||||
} while (u64_stats_fetch_retry_bh(&np->swstats_tx_syncp, syncp_start));
|
||||
} while (u64_stats_fetch_retry_irq(&np->swstats_tx_syncp, syncp_start));
|
||||
|
||||
/* If the nic supports hw counters then retrieve latest values */
|
||||
if (np->driver_data & DEV_HAS_STATISTICS_V123) {
|
||||
@@ -5544,6 +5544,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
|
||||
spin_lock_init(&np->lock);
|
||||
spin_lock_init(&np->hwstats_lock);
|
||||
SET_NETDEV_DEV(dev, &pci_dev->dev);
|
||||
u64_stats_init(&np->swstats_rx_syncp);
|
||||
u64_stats_init(&np->swstats_tx_syncp);
|
||||
|
||||
init_timer(&np->oom_kick);
|
||||
np->oom_kick.data = (unsigned long) dev;
|
||||
|
||||
@@ -828,6 +828,9 @@ retry:
|
||||
/* enable PCI bus-mastering */
|
||||
pci_set_master (pdev);
|
||||
|
||||
u64_stats_init(&tp->rx_stats.syncp);
|
||||
u64_stats_init(&tp->tx_stats.syncp);
|
||||
|
||||
if (use_io) {
|
||||
ioaddr = pci_iomap(pdev, 0, 0);
|
||||
if (!ioaddr) {
|
||||
@@ -2547,16 +2550,16 @@ rtl8139_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
||||
netdev_stats_to_stats64(stats, &dev->stats);
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&tp->rx_stats.syncp);
|
||||
start = u64_stats_fetch_begin_irq(&tp->rx_stats.syncp);
|
||||
stats->rx_packets = tp->rx_stats.packets;
|
||||
stats->rx_bytes = tp->rx_stats.bytes;
|
||||
} while (u64_stats_fetch_retry_bh(&tp->rx_stats.syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&tp->rx_stats.syncp, start));
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&tp->tx_stats.syncp);
|
||||
start = u64_stats_fetch_begin_irq(&tp->tx_stats.syncp);
|
||||
stats->tx_packets = tp->tx_stats.packets;
|
||||
stats->tx_bytes = tp->tx_stats.bytes;
|
||||
} while (u64_stats_fetch_retry_bh(&tp->tx_stats.syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&tp->tx_stats.syncp, start));
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
@@ -5790,17 +5790,17 @@ rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
||||
rtl8169_rx_missed(dev, ioaddr);
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&tp->rx_stats.syncp);
|
||||
start = u64_stats_fetch_begin_irq(&tp->rx_stats.syncp);
|
||||
stats->rx_packets = tp->rx_stats.packets;
|
||||
stats->rx_bytes = tp->rx_stats.bytes;
|
||||
} while (u64_stats_fetch_retry_bh(&tp->rx_stats.syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&tp->rx_stats.syncp, start));
|
||||
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&tp->tx_stats.syncp);
|
||||
start = u64_stats_fetch_begin_irq(&tp->tx_stats.syncp);
|
||||
stats->tx_packets = tp->tx_stats.packets;
|
||||
stats->tx_bytes = tp->tx_stats.bytes;
|
||||
} while (u64_stats_fetch_retry_bh(&tp->tx_stats.syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&tp->tx_stats.syncp, start));
|
||||
|
||||
stats->rx_dropped = dev->stats.rx_dropped;
|
||||
stats->tx_dropped = dev->stats.tx_dropped;
|
||||
|
||||
@@ -1093,6 +1093,8 @@ static void tile_net_register(void *dev_ptr)
|
||||
info->egress_timer.data = (long)info;
|
||||
info->egress_timer.function = tile_net_handle_egress_timer;
|
||||
|
||||
u64_stats_init(&info->stats.syncp);
|
||||
|
||||
priv->cpu[my_cpu] = info;
|
||||
|
||||
/*
|
||||
|
||||
@@ -975,6 +975,9 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
|
||||
dev->base_addr = (unsigned long)ioaddr;
|
||||
rp->base = ioaddr;
|
||||
|
||||
u64_stats_init(&rp->tx_stats.syncp);
|
||||
u64_stats_init(&rp->rx_stats.syncp);
|
||||
|
||||
/* Get chip registers into a sane state */
|
||||
rhine_power_init(dev);
|
||||
rhine_hw_init(dev, pioaddr);
|
||||
|
||||
+9
-4
@@ -136,18 +136,18 @@ static struct rtnl_link_stats64 *ifb_stats64(struct net_device *dev,
|
||||
unsigned int start;
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&dp->rsync);
|
||||
start = u64_stats_fetch_begin_irq(&dp->rsync);
|
||||
stats->rx_packets = dp->rx_packets;
|
||||
stats->rx_bytes = dp->rx_bytes;
|
||||
} while (u64_stats_fetch_retry_bh(&dp->rsync, start));
|
||||
} while (u64_stats_fetch_retry_irq(&dp->rsync, start));
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&dp->tsync);
|
||||
start = u64_stats_fetch_begin_irq(&dp->tsync);
|
||||
|
||||
stats->tx_packets = dp->tx_packets;
|
||||
stats->tx_bytes = dp->tx_bytes;
|
||||
|
||||
} while (u64_stats_fetch_retry_bh(&dp->tsync, start));
|
||||
} while (u64_stats_fetch_retry_irq(&dp->tsync, start));
|
||||
|
||||
stats->rx_dropped = dev->stats.rx_dropped;
|
||||
stats->tx_dropped = dev->stats.tx_dropped;
|
||||
@@ -264,6 +264,7 @@ MODULE_PARM_DESC(numifbs, "Number of ifb devices");
|
||||
static int __init ifb_init_one(int index)
|
||||
{
|
||||
struct net_device *dev_ifb;
|
||||
struct ifb_private *dp;
|
||||
int err;
|
||||
|
||||
dev_ifb = alloc_netdev(sizeof(struct ifb_private),
|
||||
@@ -272,6 +273,10 @@ static int __init ifb_init_one(int index)
|
||||
if (!dev_ifb)
|
||||
return -ENOMEM;
|
||||
|
||||
dp = netdev_priv(dev_ifb);
|
||||
u64_stats_init(&dp->rsync);
|
||||
u64_stats_init(&dp->tsync);
|
||||
|
||||
dev_ifb->rtnl_link_ops = &ifb_link_ops;
|
||||
err = register_netdevice(dev_ifb);
|
||||
if (err < 0)
|
||||
|
||||
@@ -137,10 +137,16 @@ static const struct ethtool_ops loopback_ethtool_ops = {
|
||||
|
||||
static int loopback_dev_init(struct net_device *dev)
|
||||
{
|
||||
int i;
|
||||
dev->lstats = alloc_percpu(struct pcpu_lstats);
|
||||
if (!dev->lstats)
|
||||
return -ENOMEM;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct pcpu_lstats *lb_stats;
|
||||
lb_stats = per_cpu_ptr(dev->lstats, i);
|
||||
u64_stats_init(&lb_stats->syncp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -452,6 +452,7 @@ static int macvlan_init(struct net_device *dev)
|
||||
{
|
||||
struct macvlan_dev *vlan = netdev_priv(dev);
|
||||
const struct net_device *lowerdev = vlan->lowerdev;
|
||||
int i;
|
||||
|
||||
dev->state = (dev->state & ~MACVLAN_STATE_MASK) |
|
||||
(lowerdev->state & MACVLAN_STATE_MASK);
|
||||
@@ -468,6 +469,12 @@ static int macvlan_init(struct net_device *dev)
|
||||
if (!vlan->pcpu_stats)
|
||||
return -ENOMEM;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct macvlan_pcpu_stats *mvlstats;
|
||||
mvlstats = per_cpu_ptr(vlan->pcpu_stats, i);
|
||||
u64_stats_init(&mvlstats->syncp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -498,13 +505,13 @@ static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev,
|
||||
for_each_possible_cpu(i) {
|
||||
p = per_cpu_ptr(vlan->pcpu_stats, i);
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&p->syncp);
|
||||
start = u64_stats_fetch_begin_irq(&p->syncp);
|
||||
rx_packets = p->rx_packets;
|
||||
rx_bytes = p->rx_bytes;
|
||||
rx_multicast = p->rx_multicast;
|
||||
tx_packets = p->tx_packets;
|
||||
tx_bytes = p->tx_bytes;
|
||||
} while (u64_stats_fetch_retry_bh(&p->syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&p->syncp, start));
|
||||
|
||||
stats->rx_packets += rx_packets;
|
||||
stats->rx_bytes += rx_bytes;
|
||||
|
||||
@@ -747,6 +747,12 @@ static int team_init(struct net_device *dev)
|
||||
if (!team->pcpu_stats)
|
||||
return -ENOMEM;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct team_pcpu_stats *team_stats;
|
||||
team_stats = per_cpu_ptr(team->pcpu_stats, i);
|
||||
u64_stats_init(&team_stats->syncp);
|
||||
}
|
||||
|
||||
for (i = 0; i < TEAM_PORT_HASHENTRIES; i++)
|
||||
INIT_HLIST_HEAD(&team->port_hlist[i]);
|
||||
INIT_LIST_HEAD(&team->port_list);
|
||||
@@ -925,13 +931,13 @@ team_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
||||
for_each_possible_cpu(i) {
|
||||
p = per_cpu_ptr(team->pcpu_stats, i);
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&p->syncp);
|
||||
start = u64_stats_fetch_begin_irq(&p->syncp);
|
||||
rx_packets = p->rx_packets;
|
||||
rx_bytes = p->rx_bytes;
|
||||
rx_multicast = p->rx_multicast;
|
||||
tx_packets = p->tx_packets;
|
||||
tx_bytes = p->tx_bytes;
|
||||
} while (u64_stats_fetch_retry_bh(&p->syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&p->syncp, start));
|
||||
|
||||
stats->rx_packets += rx_packets;
|
||||
stats->rx_bytes += rx_bytes;
|
||||
|
||||
+10
-2
@@ -171,13 +171,13 @@ static struct rtnl_link_stats64 *veth_get_stats64(struct net_device *dev,
|
||||
unsigned int start;
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&stats->syncp);
|
||||
start = u64_stats_fetch_begin_irq(&stats->syncp);
|
||||
rx_packets = stats->rx_packets;
|
||||
tx_packets = stats->tx_packets;
|
||||
rx_bytes = stats->rx_bytes;
|
||||
tx_bytes = stats->tx_bytes;
|
||||
rx_dropped = stats->rx_dropped;
|
||||
} while (u64_stats_fetch_retry_bh(&stats->syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&stats->syncp, start));
|
||||
tot->rx_packets += rx_packets;
|
||||
tot->tx_packets += tx_packets;
|
||||
tot->rx_bytes += rx_bytes;
|
||||
@@ -230,6 +230,7 @@ static int veth_dev_init(struct net_device *dev)
|
||||
{
|
||||
struct veth_net_stats __percpu *stats;
|
||||
struct veth_priv *priv;
|
||||
int i;
|
||||
|
||||
stats = alloc_percpu(struct veth_net_stats);
|
||||
if (stats == NULL)
|
||||
@@ -237,6 +238,13 @@ static int veth_dev_init(struct net_device *dev)
|
||||
|
||||
priv = netdev_priv(dev);
|
||||
priv->stats = stats;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct pcpu_vstats *veth_stats;
|
||||
veth_stats = per_cpu_ptr(dev->vstats, i);
|
||||
u64_stats_init(&veth_stats->syncp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1077,6 +1077,13 @@ static int virtnet_probe(struct virtio_device *vdev)
|
||||
if (vi->stats == NULL)
|
||||
goto free;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct virtnet_stats *virtnet_stats;
|
||||
virtnet_stats = per_cpu_ptr(vi->stats, i);
|
||||
u64_stats_init(&virtnet_stats->tx_syncp);
|
||||
u64_stats_init(&virtnet_stats->rx_syncp);
|
||||
}
|
||||
|
||||
INIT_DELAYED_WORK(&vi->refill, refill_work);
|
||||
sg_init_table(vi->rx_sg, ARRAY_SIZE(vi->rx_sg));
|
||||
sg_init_table(vi->tx_sg, ARRAY_SIZE(vi->tx_sg));
|
||||
|
||||
@@ -1076,13 +1076,13 @@ static struct rtnl_link_stats64 *xennet_get_stats64(struct net_device *dev,
|
||||
unsigned int start;
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&stats->syncp);
|
||||
start = u64_stats_fetch_begin_irq(&stats->syncp);
|
||||
|
||||
rx_packets = stats->rx_packets;
|
||||
tx_packets = stats->tx_packets;
|
||||
rx_bytes = stats->rx_bytes;
|
||||
tx_bytes = stats->tx_bytes;
|
||||
} while (u64_stats_fetch_retry_bh(&stats->syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&stats->syncp, start));
|
||||
|
||||
tot->rx_packets += rx_packets;
|
||||
tot->tx_packets += tx_packets;
|
||||
@@ -1314,6 +1314,12 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev
|
||||
if (np->stats == NULL)
|
||||
goto exit;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct netfront_stats *xen_nf_stats;
|
||||
xen_nf_stats = per_cpu_ptr(np->stats, i);
|
||||
u64_stats_init(&xen_nf_stats->syncp);
|
||||
}
|
||||
|
||||
/* Initialise tx_skbs as a free chain containing every entry. */
|
||||
np->tx_skb_freelist = 0;
|
||||
for (i = 0; i < NET_TX_RING_SIZE; i++) {
|
||||
|
||||
@@ -72,4 +72,6 @@
|
||||
/* Instruct lower device to use last 4-bytes of skb data as FCS */
|
||||
#define SO_NOFCS 43
|
||||
|
||||
#define SO_MAX_PACING_RATE 44
|
||||
|
||||
#endif /* __ASM_GENERIC_SOCKET_H */
|
||||
|
||||
+26
-1
@@ -168,6 +168,12 @@ struct tcp_info {
|
||||
__u32 tcpi_rcv_space;
|
||||
|
||||
__u32 tcpi_total_retrans;
|
||||
|
||||
__u64 tcpi_pacing_rate;
|
||||
__u64 tcpi_max_pacing_rate;
|
||||
__u64 tcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */
|
||||
__u32 tcpi_segs_out; /* RFC4898 tcpEStatsPerfSegsOut */
|
||||
__u32 tcpi_segs_in; /* RFC4898 tcpEStatsPerfSegsIn */
|
||||
};
|
||||
|
||||
/* for TCP_MD5SIG socket option */
|
||||
@@ -314,16 +320,30 @@ struct tcp_sock {
|
||||
* read the code and the spec side by side (and laugh ...)
|
||||
* See RFC793 and RFC1122. The RFC writes these in capitals.
|
||||
*/
|
||||
u32 segs_in; /* RFC4898 tcpEStatsPerfSegsIn
|
||||
* total number of segments in.
|
||||
*/
|
||||
u32 rcv_nxt; /* What we want to receive next */
|
||||
u32 copied_seq; /* Head of yet unread data */
|
||||
u32 rcv_wup; /* rcv_nxt on last window update sent */
|
||||
u32 snd_nxt; /* Next sequence we send */
|
||||
u32 segs_out; /* RFC4898 tcpEStatsPerfSegsOut
|
||||
* The total number of segments sent.
|
||||
*/
|
||||
u64 bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked
|
||||
* sum(delta(snd_una)), or how many bytes
|
||||
* were acked.
|
||||
*/
|
||||
struct u64_stats_sync syncp; /* protects 64bit vars (cf tcp_get_info()) */
|
||||
|
||||
u32 snd_una; /* First byte we want an ack for */
|
||||
u32 snd_sml; /* Last byte of the most recently transmitted small packet */
|
||||
u32 rcv_tstamp; /* timestamp of last received ACK (for keepalives) */
|
||||
u32 lsndtime; /* timestamp of last sent data packet (for restart window) */
|
||||
|
||||
struct list_head tsq_node; /* anchor in tsq_tasklet.head list */
|
||||
unsigned long tsq_flags;
|
||||
|
||||
/* Data for direct copy to user */
|
||||
struct {
|
||||
struct sk_buff_head prequeue;
|
||||
@@ -398,7 +418,6 @@ struct tcp_sock {
|
||||
u32 sacked_out; /* SACK'd packets */
|
||||
u32 fackets_out; /* FACK'd packets */
|
||||
u32 tso_deferred;
|
||||
u32 bytes_acked; /* Appropriate Byte Counting - RFC3465 */
|
||||
|
||||
/* from STCP, retrans queue hinting */
|
||||
struct sk_buff* lost_skb_hint;
|
||||
@@ -475,6 +494,12 @@ struct tcp_sock {
|
||||
struct tcp_cookie_values *cookie_values;
|
||||
};
|
||||
|
||||
enum tsq_flags {
|
||||
TSQ_THROTTLED,
|
||||
TSQ_QUEUED,
|
||||
TSQ_OWNED, /* tcp_tasklet_func() found socket was locked */
|
||||
};
|
||||
|
||||
static inline struct tcp_sock *tcp_sk(const struct sock *sk)
|
||||
{
|
||||
return (struct tcp_sock *)sk;
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
* (On UP, there is no seqcount_t protection, a reader allowing interrupts could
|
||||
* read partial values)
|
||||
*
|
||||
* 7) For softirq uses, readers can use u64_stats_fetch_begin_bh() and
|
||||
* u64_stats_fetch_retry_bh() helpers
|
||||
* 7) For irq and softirq uses, readers can use u64_stats_fetch_begin_irq() and
|
||||
* u64_stats_fetch_retry_irq() helpers
|
||||
*
|
||||
* Usage :
|
||||
*
|
||||
@@ -67,6 +67,13 @@ struct u64_stats_sync {
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#if BITS_PER_LONG == 32 && defined(CONFIG_SMP)
|
||||
# define u64_stats_init(syncp) seqcount_init(syncp.seq)
|
||||
#else
|
||||
# define u64_stats_init(syncp) do { } while (0)
|
||||
#endif
|
||||
|
||||
static inline void u64_stats_update_begin(struct u64_stats_sync *syncp)
|
||||
{
|
||||
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
|
||||
@@ -107,31 +114,31 @@ static inline bool u64_stats_fetch_retry(const struct u64_stats_sync *syncp,
|
||||
}
|
||||
|
||||
/*
|
||||
* In case softirq handlers can update u64 counters, readers can use following helpers
|
||||
* In case irq handlers can update u64 counters, readers can use following helpers
|
||||
* - SMP 32bit arches use seqcount protection, irq safe.
|
||||
* - UP 32bit must disable BH.
|
||||
* - UP 32bit must disable irqs.
|
||||
* - 64bit have no problem atomically reading u64 values, irq safe.
|
||||
*/
|
||||
static inline unsigned int u64_stats_fetch_begin_bh(const struct u64_stats_sync *syncp)
|
||||
static inline unsigned int u64_stats_fetch_begin_irq(const struct u64_stats_sync *syncp)
|
||||
{
|
||||
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
|
||||
return read_seqcount_begin(&syncp->seq);
|
||||
#else
|
||||
#if BITS_PER_LONG==32
|
||||
local_bh_disable();
|
||||
local_irq_disable();
|
||||
#endif
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool u64_stats_fetch_retry_bh(const struct u64_stats_sync *syncp,
|
||||
static inline bool u64_stats_fetch_retry_irq(const struct u64_stats_sync *syncp,
|
||||
unsigned int start)
|
||||
{
|
||||
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
|
||||
return read_seqcount_retry(&syncp->seq, start);
|
||||
#else
|
||||
#if BITS_PER_LONG==32
|
||||
local_bh_enable();
|
||||
local_irq_enable();
|
||||
#endif
|
||||
return false;
|
||||
#endif
|
||||
|
||||
@@ -55,8 +55,10 @@ struct ip_tunnel_prl_entry {
|
||||
\
|
||||
err = ip_local_out(skb); \
|
||||
if (likely(net_xmit_eval(err) == 0)) { \
|
||||
u64_stats_update_begin(&(stats1)->syncp); \
|
||||
(stats1)->tx_bytes += pkt_len; \
|
||||
(stats1)->tx_packets++; \
|
||||
u64_stats_update_end(&(stats1)->syncp); \
|
||||
} else { \
|
||||
(stats2)->tx_errors++; \
|
||||
(stats2)->tx_aborted_errors++; \
|
||||
|
||||
@@ -220,6 +220,8 @@ struct cg_proto;
|
||||
* @sk_wmem_queued: persistent queue size
|
||||
* @sk_forward_alloc: space allocated forward
|
||||
* @sk_allocation: allocation mode
|
||||
* @sk_pacing_rate: Pacing rate (if supported by transport/packet scheduler)
|
||||
* @sk_max_pacing_rate: Maximum pacing rate (%SO_MAX_PACING_RATE)
|
||||
* @sk_sndbuf: size of send buffer in bytes
|
||||
* @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE,
|
||||
* %SO_OOBINLINE settings, %SO_TIMESTAMPING settings
|
||||
@@ -345,6 +347,8 @@ struct sock {
|
||||
kmemcheck_bitfield_end(flags);
|
||||
int sk_wmem_queued;
|
||||
gfp_t sk_allocation;
|
||||
u32 sk_pacing_rate; /* bytes per second */
|
||||
u32 sk_max_pacing_rate;
|
||||
netdev_features_t sk_route_caps;
|
||||
netdev_features_t sk_route_nocaps;
|
||||
int sk_gso_type;
|
||||
@@ -869,6 +873,8 @@ struct proto {
|
||||
int (*backlog_rcv) (struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
|
||||
void (*release_cb)(struct sock *sk);
|
||||
|
||||
/* Keeping track of sk's, looking them up, and port selection methods. */
|
||||
void (*hash)(struct sock *sk);
|
||||
void (*unhash)(struct sock *sk);
|
||||
|
||||
+7
-2
@@ -251,7 +251,6 @@ extern int sysctl_tcp_dma_copybreak;
|
||||
extern int sysctl_tcp_nometrics_save;
|
||||
extern int sysctl_tcp_moderate_rcvbuf;
|
||||
extern int sysctl_tcp_tso_win_divisor;
|
||||
extern int sysctl_tcp_abc;
|
||||
extern int sysctl_tcp_mtu_probing;
|
||||
extern int sysctl_tcp_base_mss;
|
||||
extern int sysctl_tcp_min_snd_mss;
|
||||
@@ -261,6 +260,8 @@ extern int sysctl_tcp_max_ssthresh;
|
||||
extern int sysctl_tcp_cookie_size;
|
||||
extern int sysctl_tcp_thin_linear_timeouts;
|
||||
extern int sysctl_tcp_thin_dupack;
|
||||
extern int sysctl_tcp_limit_output_bytes;
|
||||
extern int sysctl_tcp_min_tso_segs;
|
||||
extern int sysctl_tcp_default_init_rwnd;
|
||||
|
||||
/* sysctl variables for controlling various tcp parameters */
|
||||
@@ -339,6 +340,8 @@ extern struct proto tcp_prot;
|
||||
|
||||
extern void tcp_init_mem(struct net *net);
|
||||
|
||||
extern void tcp_tasklet_init(void);
|
||||
|
||||
extern void tcp_v4_err(struct sk_buff *skb, u32);
|
||||
|
||||
extern void tcp_shutdown (struct sock *sk, int how);
|
||||
@@ -352,6 +355,8 @@ extern int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
|
||||
size_t size);
|
||||
extern int tcp_sendpage(struct sock *sk, struct page *page, int offset,
|
||||
size_t size, int flags);
|
||||
extern void tcp_release_cb(struct sock *sk);
|
||||
extern void tcp_wfree(struct sk_buff *skb);
|
||||
extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg);
|
||||
extern int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
|
||||
const struct tcphdr *th, unsigned int len);
|
||||
@@ -553,7 +558,7 @@ static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize)
|
||||
}
|
||||
|
||||
/* tcp.c */
|
||||
extern void tcp_get_info(const struct sock *, struct tcp_info *);
|
||||
void tcp_get_info(struct sock *, struct tcp_info *);
|
||||
|
||||
/* Read 'sendfile()'-style from a TCP socket */
|
||||
typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *,
|
||||
|
||||
@@ -389,7 +389,6 @@ static const struct bin_table bin_net_ipv4_table[] = {
|
||||
{ CTL_INT, NET_TCP_MODERATE_RCVBUF, "tcp_moderate_rcvbuf" },
|
||||
{ CTL_INT, NET_TCP_TSO_WIN_DIVISOR, "tcp_tso_win_divisor" },
|
||||
{ CTL_STR, NET_TCP_CONG_CONTROL, "tcp_congestion_control" },
|
||||
{ CTL_INT, NET_TCP_ABC, "tcp_abc" },
|
||||
{ CTL_INT, NET_TCP_MTU_PROBING, "tcp_mtu_probing" },
|
||||
{ CTL_INT, NET_TCP_BASE_MSS, "tcp_base_mss" },
|
||||
{ CTL_INT, NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS, "tcp_workaround_signed_windows" },
|
||||
|
||||
+10
-3
@@ -550,7 +550,7 @@ static const struct net_device_ops vlan_netdev_ops;
|
||||
static int vlan_dev_init(struct net_device *dev)
|
||||
{
|
||||
struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
|
||||
int subclass = 0;
|
||||
int subclass = 0, i;
|
||||
|
||||
netif_carrier_off(dev);
|
||||
|
||||
@@ -602,6 +602,13 @@ static int vlan_dev_init(struct net_device *dev)
|
||||
if (!vlan_dev_priv(dev)->vlan_pcpu_stats)
|
||||
return -ENOMEM;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct vlan_pcpu_stats *vlan_stat;
|
||||
vlan_stat = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, i);
|
||||
u64_stats_init(&vlan_stat->syncp);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -667,13 +674,13 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st
|
||||
|
||||
p = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, i);
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&p->syncp);
|
||||
start = u64_stats_fetch_begin_irq(&p->syncp);
|
||||
rxpackets = p->rx_packets;
|
||||
rxbytes = p->rx_bytes;
|
||||
rxmulticast = p->rx_multicast;
|
||||
txpackets = p->tx_packets;
|
||||
txbytes = p->tx_bytes;
|
||||
} while (u64_stats_fetch_retry_bh(&p->syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&p->syncp, start));
|
||||
|
||||
stats->rx_packets += rxpackets;
|
||||
stats->rx_bytes += rxbytes;
|
||||
|
||||
@@ -80,11 +80,18 @@ out:
|
||||
static int br_dev_init(struct net_device *dev)
|
||||
{
|
||||
struct net_bridge *br = netdev_priv(dev);
|
||||
int i;
|
||||
|
||||
br->stats = alloc_percpu(struct br_cpu_netstats);
|
||||
if (!br->stats)
|
||||
return -ENOMEM;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct br_cpu_netstats *br_dev_stats;
|
||||
br_dev_stats = per_cpu_ptr(br->stats, i);
|
||||
u64_stats_init(&br_dev_stats->syncp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -802,6 +802,12 @@ set_rcvbuf:
|
||||
sock_valbool_flag(sk, SOCK_NOFCS, valbool);
|
||||
break;
|
||||
|
||||
case SO_MAX_PACING_RATE:
|
||||
sk->sk_max_pacing_rate = val;
|
||||
sk->sk_pacing_rate = min(sk->sk_pacing_rate,
|
||||
sk->sk_max_pacing_rate);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -ENOPROTOOPT;
|
||||
break;
|
||||
@@ -1042,6 +1048,11 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
|
||||
case SO_NOFCS:
|
||||
v.val = !!sock_flag(sk, SOCK_NOFCS);
|
||||
break;
|
||||
|
||||
case SO_MAX_PACING_RATE:
|
||||
v.val = sk->sk_max_pacing_rate;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOPROTOOPT;
|
||||
}
|
||||
@@ -2123,6 +2134,8 @@ void sock_init_data(struct socket *sock, struct sock *sk)
|
||||
|
||||
sk->sk_stamp = ktime_set(-1L, 0);
|
||||
|
||||
sk->sk_max_pacing_rate = ~0U;
|
||||
|
||||
/*
|
||||
* Before updating sk_refcnt, we must commit prior changes to memory
|
||||
* (Documentation/RCU/rculist_nulls.txt for details)
|
||||
@@ -2159,6 +2172,10 @@ void release_sock(struct sock *sk)
|
||||
spin_lock_bh(&sk->sk_lock.slock);
|
||||
if (sk->sk_backlog.tail)
|
||||
__release_sock(sk);
|
||||
|
||||
if (sk->sk_prot->release_cb)
|
||||
sk->sk_prot->release_cb(sk);
|
||||
|
||||
sk->sk_lock.owned = 0;
|
||||
if (waitqueue_active(&sk->sk_lock.wq))
|
||||
wake_up(&sk->sk_lock.wq);
|
||||
|
||||
+16
-2
@@ -1501,9 +1501,9 @@ u64 snmp_fold_field64(void __percpu *mib[], int offt, size_t syncp_offset)
|
||||
bhptr = per_cpu_ptr(mib[0], cpu);
|
||||
syncp = (struct u64_stats_sync *)(bhptr + syncp_offset);
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(syncp);
|
||||
start = u64_stats_fetch_begin_irq(syncp);
|
||||
v = *(((u64 *) bhptr) + offt);
|
||||
} while (u64_stats_fetch_retry_bh(syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(syncp, start));
|
||||
|
||||
res += v;
|
||||
}
|
||||
@@ -1518,6 +1518,7 @@ int snmp_mib_init(void __percpu *ptr[2], size_t mibsize, size_t align)
|
||||
ptr[0] = __alloc_percpu(mibsize, align);
|
||||
if (!ptr[0])
|
||||
return -ENOMEM;
|
||||
|
||||
#if SNMP_ARRAY_SZ == 2
|
||||
ptr[1] = __alloc_percpu(mibsize, align);
|
||||
if (!ptr[1]) {
|
||||
@@ -1578,6 +1579,8 @@ static const struct net_protocol icmp_protocol = {
|
||||
|
||||
static __net_init int ipv4_mib_init_net(struct net *net)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (snmp_mib_init((void __percpu **)net->mib.tcp_statistics,
|
||||
sizeof(struct tcp_mib),
|
||||
__alignof__(struct tcp_mib)) < 0)
|
||||
@@ -1586,6 +1589,17 @@ static __net_init int ipv4_mib_init_net(struct net *net)
|
||||
sizeof(struct ipstats_mib),
|
||||
__alignof__(struct ipstats_mib)) < 0)
|
||||
goto err_ip_mib;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct ipstats_mib *af_inet_stats;
|
||||
af_inet_stats = per_cpu_ptr(net->mib.ip_statistics[0], i);
|
||||
u64_stats_init(&af_inet_stats->syncp);
|
||||
#if SNMP_ARRAY_SZ == 2
|
||||
af_inet_stats = per_cpu_ptr(net->mib.ip_statistics[1], i);
|
||||
u64_stats_init(&af_inet_stats->syncp);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (snmp_mib_init((void __percpu **)net->mib.net_statistics,
|
||||
sizeof(struct linux_mib),
|
||||
__alignof__(struct linux_mib)) < 0)
|
||||
|
||||
+39
-18
@@ -169,30 +169,49 @@ struct ipgre_net {
|
||||
|
||||
/* often modified stats are per cpu, other are shared (netdev->stats) */
|
||||
struct pcpu_tstats {
|
||||
unsigned long rx_packets;
|
||||
unsigned long rx_bytes;
|
||||
unsigned long tx_packets;
|
||||
unsigned long tx_bytes;
|
||||
} __attribute__((aligned(4*sizeof(unsigned long))));
|
||||
u64 rx_packets;
|
||||
u64 rx_bytes;
|
||||
u64 tx_packets;
|
||||
u64 tx_bytes;
|
||||
struct u64_stats_sync syncp;
|
||||
};
|
||||
|
||||
static struct net_device_stats *ipgre_get_stats(struct net_device *dev)
|
||||
static struct rtnl_link_stats64 *ipgre_get_stats64(struct net_device *dev,
|
||||
struct rtnl_link_stats64 *tot)
|
||||
{
|
||||
struct pcpu_tstats sum = { 0 };
|
||||
int i;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
|
||||
u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
|
||||
unsigned int start;
|
||||
|
||||
sum.rx_packets += tstats->rx_packets;
|
||||
sum.rx_bytes += tstats->rx_bytes;
|
||||
sum.tx_packets += tstats->tx_packets;
|
||||
sum.tx_bytes += tstats->tx_bytes;
|
||||
do {
|
||||
start = u64_stats_fetch_begin_irq(&tstats->syncp);
|
||||
rx_packets = tstats->rx_packets;
|
||||
tx_packets = tstats->tx_packets;
|
||||
rx_bytes = tstats->rx_bytes;
|
||||
tx_bytes = tstats->tx_bytes;
|
||||
} while (u64_stats_fetch_retry_irq(&tstats->syncp, start));
|
||||
|
||||
tot->rx_packets += rx_packets;
|
||||
tot->tx_packets += tx_packets;
|
||||
tot->rx_bytes += rx_bytes;
|
||||
tot->tx_bytes += tx_bytes;
|
||||
}
|
||||
dev->stats.rx_packets = sum.rx_packets;
|
||||
dev->stats.rx_bytes = sum.rx_bytes;
|
||||
dev->stats.tx_packets = sum.tx_packets;
|
||||
dev->stats.tx_bytes = sum.tx_bytes;
|
||||
return &dev->stats;
|
||||
|
||||
tot->multicast = dev->stats.multicast;
|
||||
tot->rx_crc_errors = dev->stats.rx_crc_errors;
|
||||
tot->rx_fifo_errors = dev->stats.rx_fifo_errors;
|
||||
tot->rx_length_errors = dev->stats.rx_length_errors;
|
||||
tot->rx_errors = dev->stats.rx_errors;
|
||||
tot->tx_fifo_errors = dev->stats.tx_fifo_errors;
|
||||
tot->tx_carrier_errors = dev->stats.tx_carrier_errors;
|
||||
tot->tx_dropped = dev->stats.tx_dropped;
|
||||
tot->tx_aborted_errors = dev->stats.tx_aborted_errors;
|
||||
tot->tx_errors = dev->stats.tx_errors;
|
||||
|
||||
return tot;
|
||||
}
|
||||
|
||||
/* Given src, dst and key, find appropriate for input tunnel. */
|
||||
@@ -672,8 +691,10 @@ static int ipgre_rcv(struct sk_buff *skb)
|
||||
}
|
||||
|
||||
tstats = this_cpu_ptr(tunnel->dev->tstats);
|
||||
u64_stats_update_begin(&tstats->syncp);
|
||||
tstats->rx_packets++;
|
||||
tstats->rx_bytes += skb->len;
|
||||
u64_stats_update_end(&tstats->syncp);
|
||||
|
||||
__skb_tunnel_rx(skb, tunnel->dev);
|
||||
|
||||
@@ -1253,7 +1274,7 @@ static const struct net_device_ops ipgre_netdev_ops = {
|
||||
.ndo_start_xmit = ipgre_tunnel_xmit,
|
||||
.ndo_do_ioctl = ipgre_tunnel_ioctl,
|
||||
.ndo_change_mtu = ipgre_tunnel_change_mtu,
|
||||
.ndo_get_stats = ipgre_get_stats,
|
||||
.ndo_get_stats64 = ipgre_get_stats64,
|
||||
};
|
||||
|
||||
static void ipgre_dev_free(struct net_device *dev)
|
||||
@@ -1507,7 +1528,7 @@ static const struct net_device_ops ipgre_tap_netdev_ops = {
|
||||
.ndo_set_mac_address = eth_mac_addr,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
.ndo_change_mtu = ipgre_tunnel_change_mtu,
|
||||
.ndo_get_stats = ipgre_get_stats,
|
||||
.ndo_get_stats64 = ipgre_get_stats64,
|
||||
};
|
||||
|
||||
static void ipgre_tap_setup(struct net_device *dev)
|
||||
|
||||
+34
-17
@@ -144,30 +144,45 @@ static void ipip_dev_free(struct net_device *dev);
|
||||
|
||||
/* often modified stats are per cpu, other are shared (netdev->stats) */
|
||||
struct pcpu_tstats {
|
||||
unsigned long rx_packets;
|
||||
unsigned long rx_bytes;
|
||||
unsigned long tx_packets;
|
||||
unsigned long tx_bytes;
|
||||
} __attribute__((aligned(4*sizeof(unsigned long))));
|
||||
u64 rx_packets;
|
||||
u64 rx_bytes;
|
||||
u64 tx_packets;
|
||||
u64 tx_bytes;
|
||||
struct u64_stats_sync syncp;
|
||||
};
|
||||
|
||||
static struct net_device_stats *ipip_get_stats(struct net_device *dev)
|
||||
static struct rtnl_link_stats64 *ipip_get_stats64(struct net_device *dev,
|
||||
struct rtnl_link_stats64 *tot)
|
||||
{
|
||||
struct pcpu_tstats sum = { 0 };
|
||||
int i;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
|
||||
u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
|
||||
unsigned int start;
|
||||
|
||||
sum.rx_packets += tstats->rx_packets;
|
||||
sum.rx_bytes += tstats->rx_bytes;
|
||||
sum.tx_packets += tstats->tx_packets;
|
||||
sum.tx_bytes += tstats->tx_bytes;
|
||||
do {
|
||||
start = u64_stats_fetch_begin_irq(&tstats->syncp);
|
||||
rx_packets = tstats->rx_packets;
|
||||
tx_packets = tstats->tx_packets;
|
||||
rx_bytes = tstats->rx_bytes;
|
||||
tx_bytes = tstats->tx_bytes;
|
||||
} while (u64_stats_fetch_retry_irq(&tstats->syncp, start));
|
||||
|
||||
tot->rx_packets += rx_packets;
|
||||
tot->tx_packets += tx_packets;
|
||||
tot->rx_bytes += rx_bytes;
|
||||
tot->tx_bytes += tx_bytes;
|
||||
}
|
||||
dev->stats.rx_packets = sum.rx_packets;
|
||||
dev->stats.rx_bytes = sum.rx_bytes;
|
||||
dev->stats.tx_packets = sum.tx_packets;
|
||||
dev->stats.tx_bytes = sum.tx_bytes;
|
||||
return &dev->stats;
|
||||
|
||||
tot->tx_fifo_errors = dev->stats.tx_fifo_errors;
|
||||
tot->tx_carrier_errors = dev->stats.tx_carrier_errors;
|
||||
tot->tx_dropped = dev->stats.tx_dropped;
|
||||
tot->tx_aborted_errors = dev->stats.tx_aborted_errors;
|
||||
tot->tx_errors = dev->stats.tx_errors;
|
||||
tot->collisions = dev->stats.collisions;
|
||||
|
||||
return tot;
|
||||
}
|
||||
|
||||
static struct ip_tunnel * ipip_tunnel_lookup(struct net *net,
|
||||
@@ -404,8 +419,10 @@ static int ipip_rcv(struct sk_buff *skb)
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
|
||||
tstats = this_cpu_ptr(tunnel->dev->tstats);
|
||||
u64_stats_update_begin(&tstats->syncp);
|
||||
tstats->rx_packets++;
|
||||
tstats->rx_bytes += skb->len;
|
||||
u64_stats_update_end(&tstats->syncp);
|
||||
|
||||
__skb_tunnel_rx(skb, tunnel->dev);
|
||||
|
||||
@@ -730,7 +747,7 @@ static const struct net_device_ops ipip_netdev_ops = {
|
||||
.ndo_start_xmit = ipip_tunnel_xmit,
|
||||
.ndo_do_ioctl = ipip_tunnel_ioctl,
|
||||
.ndo_change_mtu = ipip_tunnel_change_mtu,
|
||||
.ndo_get_stats = ipip_get_stats,
|
||||
.ndo_get_stats64 = ipip_get_stats64,
|
||||
};
|
||||
|
||||
static void ipip_dev_free(struct net_device *dev)
|
||||
|
||||
@@ -26,7 +26,9 @@
|
||||
#include <net/ping.h>
|
||||
#include <net/tcp_memcontrol.h>
|
||||
|
||||
static int zero = 0;
|
||||
static int one = 1;
|
||||
static int gso_max_segs = GSO_MAX_SEGS;
|
||||
static int tcp_retr1_max = 255;
|
||||
static int ip_local_port_range_min[] = { 1, 1 };
|
||||
static int ip_local_port_range_max[] = { 65535, 65535 };
|
||||
@@ -589,13 +591,6 @@ static struct ctl_table ipv4_table[] = {
|
||||
.maxlen = TCP_CA_NAME_MAX,
|
||||
.proc_handler = proc_tcp_congestion_control,
|
||||
},
|
||||
{
|
||||
.procname = "tcp_abc",
|
||||
.data = &sysctl_tcp_abc,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec,
|
||||
},
|
||||
{
|
||||
.procname = "tcp_mtu_probing",
|
||||
.data = &sysctl_tcp_mtu_probing,
|
||||
@@ -633,6 +628,13 @@ static struct ctl_table ipv4_table[] = {
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec
|
||||
},
|
||||
{
|
||||
.procname = "tcp_limit_output_bytes",
|
||||
.data = &sysctl_tcp_limit_output_bytes,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec
|
||||
},
|
||||
#ifdef CONFIG_NET_DMA
|
||||
{
|
||||
.procname = "tcp_dma_copybreak",
|
||||
@@ -726,6 +728,15 @@ static struct ctl_table ipv4_table[] = {
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_tcp_default_init_rwnd
|
||||
},
|
||||
{
|
||||
.procname = "tcp_min_tso_segs",
|
||||
.data = &sysctl_tcp_min_tso_segs,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = &zero,
|
||||
.extra2 = &gso_max_segs,
|
||||
},
|
||||
{
|
||||
.procname = "udp_mem",
|
||||
.data = &sysctl_udp_mem,
|
||||
|
||||
+70
-8
@@ -285,6 +285,8 @@
|
||||
|
||||
int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT;
|
||||
|
||||
int sysctl_tcp_min_tso_segs __read_mostly = 2;
|
||||
|
||||
struct percpu_counter tcp_orphan_count;
|
||||
EXPORT_SYMBOL_GPL(tcp_orphan_count);
|
||||
|
||||
@@ -740,10 +742,24 @@ static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now,
|
||||
xmit_size_goal = mss_now;
|
||||
|
||||
if (large_allowed && sk_can_gso(sk)) {
|
||||
xmit_size_goal = ((sk->sk_gso_max_size - 1) -
|
||||
inet_csk(sk)->icsk_af_ops->net_header_len -
|
||||
inet_csk(sk)->icsk_ext_hdr_len -
|
||||
tp->tcp_header_len);
|
||||
u32 gso_size, hlen;
|
||||
|
||||
/* Maybe we should/could use sk->sk_prot->max_header here ? */
|
||||
hlen = inet_csk(sk)->icsk_af_ops->net_header_len +
|
||||
inet_csk(sk)->icsk_ext_hdr_len +
|
||||
tp->tcp_header_len;
|
||||
|
||||
/* Goal is to send at least one packet per ms,
|
||||
* not one big TSO packet every 100 ms.
|
||||
* This preserves ACK clocking and is consistent
|
||||
* with tcp_tso_should_defer() heuristic.
|
||||
*/
|
||||
gso_size = sk->sk_pacing_rate / (2 * MSEC_PER_SEC);
|
||||
gso_size = max_t(u32, gso_size,
|
||||
sysctl_tcp_min_tso_segs * mss_now);
|
||||
|
||||
xmit_size_goal = min_t(u32, gso_size,
|
||||
sk->sk_gso_max_size - 1 - hlen);
|
||||
|
||||
xmit_size_goal = tcp_bound_to_half_wnd(tp, xmit_size_goal);
|
||||
|
||||
@@ -2146,7 +2162,6 @@ int tcp_disconnect(struct sock *sk, int flags)
|
||||
tp->packets_out = 0;
|
||||
tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
|
||||
tp->snd_cwnd_cnt = 0;
|
||||
tp->bytes_acked = 0;
|
||||
tp->window_clamp = 0;
|
||||
tcp_set_ca_state(sk, TCP_CA_Open);
|
||||
tcp_clear_retrans(tp);
|
||||
@@ -2489,11 +2504,12 @@ EXPORT_SYMBOL(compat_tcp_setsockopt);
|
||||
#endif
|
||||
|
||||
/* Return information about state of tcp endpoint in API format. */
|
||||
void tcp_get_info(const struct sock *sk, struct tcp_info *info)
|
||||
void tcp_get_info(struct sock *sk, struct tcp_info *info)
|
||||
{
|
||||
const struct tcp_sock *tp = tcp_sk(sk);
|
||||
const struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
u32 now = tcp_time_stamp;
|
||||
unsigned int start;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
@@ -2552,6 +2568,19 @@ void tcp_get_info(const struct sock *sk, struct tcp_info *info)
|
||||
|
||||
info->tcpi_total_retrans = tp->total_retrans;
|
||||
|
||||
info->tcpi_pacing_rate = sk->sk_pacing_rate != ~0U ?
|
||||
sk->sk_pacing_rate : ~0ULL;
|
||||
info->tcpi_max_pacing_rate = sk->sk_max_pacing_rate != ~0U ?
|
||||
sk->sk_max_pacing_rate : ~0ULL;
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_irq(&tp->syncp);
|
||||
info->tcpi_bytes_acked = tp->bytes_acked;
|
||||
info->tcpi_bytes_received = tp->bytes_received;
|
||||
} while (u64_stats_fetch_retry_irq(&tp->syncp, start));
|
||||
info->tcpi_segs_out = tp->segs_out;
|
||||
info->tcpi_segs_in = tp->segs_in;
|
||||
|
||||
if (sk->sk_socket) {
|
||||
struct file *filep = sk->sk_socket->file;
|
||||
if (filep)
|
||||
@@ -2724,12 +2753,16 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
|
||||
netdev_features_t features)
|
||||
{
|
||||
struct sk_buff *segs = ERR_PTR(-EINVAL);
|
||||
unsigned int sum_truesize = 0;
|
||||
struct tcphdr *th;
|
||||
unsigned thlen;
|
||||
unsigned int seq;
|
||||
__be32 delta;
|
||||
unsigned int oldlen;
|
||||
unsigned int mss;
|
||||
struct sk_buff *gso_skb = skb;
|
||||
__sum16 newcheck;
|
||||
bool ooo_okay, copy_destructor;
|
||||
|
||||
if (!pskb_may_pull(skb, sizeof(*th)))
|
||||
goto out;
|
||||
@@ -2768,27 +2801,42 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
|
||||
goto out;
|
||||
}
|
||||
|
||||
copy_destructor = gso_skb->destructor == tcp_wfree;
|
||||
ooo_okay = gso_skb->ooo_okay;
|
||||
/* All segments but the first should have ooo_okay cleared */
|
||||
skb->ooo_okay = 0;
|
||||
|
||||
segs = skb_segment(skb, features);
|
||||
if (IS_ERR(segs))
|
||||
goto out;
|
||||
|
||||
/* Only first segment might have ooo_okay set */
|
||||
segs->ooo_okay = ooo_okay;
|
||||
|
||||
delta = htonl(oldlen + (thlen + mss));
|
||||
|
||||
skb = segs;
|
||||
th = tcp_hdr(skb);
|
||||
seq = ntohl(th->seq);
|
||||
|
||||
newcheck = ~csum_fold((__force __wsum)((__force u32)th->check +
|
||||
(__force u32)delta));
|
||||
|
||||
do {
|
||||
th->fin = th->psh = 0;
|
||||
th->check = newcheck;
|
||||
|
||||
th->check = ~csum_fold((__force __wsum)((__force u32)th->check +
|
||||
(__force u32)delta));
|
||||
if (skb->ip_summed != CHECKSUM_PARTIAL)
|
||||
th->check =
|
||||
csum_fold(csum_partial(skb_transport_header(skb),
|
||||
thlen, skb->csum));
|
||||
|
||||
seq += mss;
|
||||
if (copy_destructor) {
|
||||
skb->destructor = gso_skb->destructor;
|
||||
skb->sk = gso_skb->sk;
|
||||
sum_truesize += skb->truesize;
|
||||
}
|
||||
skb = skb->next;
|
||||
th = tcp_hdr(skb);
|
||||
|
||||
@@ -2796,6 +2844,19 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
|
||||
th->cwr = 0;
|
||||
} while (skb->next);
|
||||
|
||||
/* Following permits TCP Small Queues to work well with GSO :
|
||||
* The callback to TCP stack will be called at the time last frag
|
||||
* is freed at TX completion, and not right now when gso_skb
|
||||
* is freed by GSO engine
|
||||
*/
|
||||
if (copy_destructor) {
|
||||
swap(gso_skb->sk, skb->sk);
|
||||
swap(gso_skb->destructor, skb->destructor);
|
||||
sum_truesize += skb->truesize;
|
||||
atomic_add(sum_truesize - gso_skb->truesize,
|
||||
&skb->sk->sk_wmem_alloc);
|
||||
}
|
||||
|
||||
delta = htonl(oldlen + (skb->tail - skb->transport_header) +
|
||||
skb->data_len);
|
||||
th->check = ~csum_fold((__force __wsum)((__force u32)th->check +
|
||||
@@ -3418,6 +3479,7 @@ void __init tcp_init(void)
|
||||
tcp_secret_primary = &tcp_secret_one;
|
||||
tcp_secret_retiring = &tcp_secret_two;
|
||||
tcp_secret_secondary = &tcp_secret_two;
|
||||
tcp_tasklet_init();
|
||||
}
|
||||
|
||||
static int tcp_is_local(struct net *net, __be32 addr) {
|
||||
|
||||
+1
-29
@@ -310,28 +310,11 @@ void tcp_slow_start(struct tcp_sock *tp)
|
||||
{
|
||||
int cnt; /* increase in packets */
|
||||
|
||||
/* RFC3465: ABC Slow start
|
||||
* Increase only after a full MSS of bytes is acked
|
||||
*
|
||||
* TCP sender SHOULD increase cwnd by the number of
|
||||
* previously unacknowledged bytes ACKed by each incoming
|
||||
* acknowledgment, provided the increase is not more than L
|
||||
*/
|
||||
if (sysctl_tcp_abc && tp->bytes_acked < tp->mss_cache)
|
||||
return;
|
||||
|
||||
if (sysctl_tcp_max_ssthresh > 0 && tp->snd_cwnd > sysctl_tcp_max_ssthresh)
|
||||
cnt = sysctl_tcp_max_ssthresh >> 1; /* limited slow start */
|
||||
else
|
||||
cnt = tp->snd_cwnd; /* exponential increase */
|
||||
|
||||
/* RFC3465: ABC
|
||||
* We MAY increase by 2 if discovered delayed ack
|
||||
*/
|
||||
if (sysctl_tcp_abc > 1 && tp->bytes_acked >= 2*tp->mss_cache)
|
||||
cnt <<= 1;
|
||||
tp->bytes_acked = 0;
|
||||
|
||||
tp->snd_cwnd_cnt += cnt;
|
||||
while (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
|
||||
tp->snd_cwnd_cnt -= tp->snd_cwnd;
|
||||
@@ -371,20 +354,9 @@ void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
|
||||
/* In "safe" area, increase. */
|
||||
if (tp->snd_cwnd <= tp->snd_ssthresh)
|
||||
tcp_slow_start(tp);
|
||||
|
||||
/* In dangerous area, increase slowly. */
|
||||
else if (sysctl_tcp_abc) {
|
||||
/* RFC3465: Appropriate Byte Count
|
||||
* increase once for each full cwnd acked
|
||||
*/
|
||||
if (tp->bytes_acked >= tp->snd_cwnd*tp->mss_cache) {
|
||||
tp->bytes_acked -= tp->snd_cwnd*tp->mss_cache;
|
||||
if (tp->snd_cwnd < tp->snd_cwnd_clamp)
|
||||
tp->snd_cwnd++;
|
||||
}
|
||||
} else {
|
||||
else
|
||||
tcp_cong_avoid_ai(tp, tp->snd_cwnd);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tcp_reno_cong_avoid);
|
||||
|
||||
|
||||
+46
-18
@@ -101,7 +101,6 @@ int sysctl_tcp_nometrics_save __read_mostly;
|
||||
int sysctl_tcp_thin_dupack __read_mostly;
|
||||
|
||||
int sysctl_tcp_moderate_rcvbuf __read_mostly = 1;
|
||||
int sysctl_tcp_abc __read_mostly;
|
||||
int sysctl_tcp_default_init_rwnd __read_mostly = TCP_DEFAULT_INIT_RCVWND;
|
||||
|
||||
#define FLAG_DATA 0x01 /* Incoming frame contained data. */
|
||||
@@ -701,6 +700,34 @@ static void tcp_rtt_estimator(struct sock *sk, const __u32 mrtt)
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the sk_pacing_rate to allow proper sizing of TSO packets.
|
||||
* Note: TCP stack does not yet implement pacing.
|
||||
* FQ packet scheduler can be used to implement cheap but effective
|
||||
* TCP pacing, to smooth the burst on large writes when packets
|
||||
* in flight is significantly lower than cwnd (or rwin)
|
||||
*/
|
||||
static void tcp_update_pacing_rate(struct sock *sk)
|
||||
{
|
||||
const struct tcp_sock *tp = tcp_sk(sk);
|
||||
u64 rate;
|
||||
|
||||
/* set sk_pacing_rate to 200 % of current rate (mss * cwnd / srtt) */
|
||||
rate = (u64)tp->mss_cache * 2 * (HZ << 3);
|
||||
|
||||
rate *= max(tp->snd_cwnd, tp->packets_out);
|
||||
|
||||
/* Correction for small srtt : minimum srtt being 8 (1 jiffy << 3),
|
||||
* be conservative and assume srtt = 1 (125 us instead of 1.25 ms)
|
||||
* We probably need usec resolution in the future.
|
||||
* Note: This also takes care of possible srtt=0 case,
|
||||
* when tcp_rtt_estimator() was not yet called.
|
||||
*/
|
||||
if (tp->srtt > 8 + 2)
|
||||
do_div(rate, tp->srtt);
|
||||
|
||||
sk->sk_pacing_rate = min_t(u64, rate, sk->sk_max_pacing_rate);
|
||||
}
|
||||
|
||||
/* Calculate rto without backoff. This is the second half of Van Jacobson's
|
||||
* routine referred to above.
|
||||
*/
|
||||
@@ -850,7 +877,6 @@ void tcp_enter_cwr(struct sock *sk, const int set_ssthresh)
|
||||
const struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
|
||||
tp->prior_ssthresh = 0;
|
||||
tp->bytes_acked = 0;
|
||||
if (icsk->icsk_ca_state < TCP_CA_CWR) {
|
||||
tp->undo_marker = 0;
|
||||
if (set_ssthresh)
|
||||
@@ -2227,7 +2253,6 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
|
||||
tp->snd_cwnd_cnt = 0;
|
||||
tp->snd_cwnd_stamp = tcp_time_stamp;
|
||||
tp->frto_counter = 0;
|
||||
tp->bytes_acked = 0;
|
||||
|
||||
tp->reordering = min_t(unsigned int, tp->reordering,
|
||||
sysctl_tcp_reordering);
|
||||
@@ -2276,7 +2301,6 @@ void tcp_enter_loss(struct sock *sk, int how)
|
||||
tp->snd_cwnd_cnt = 0;
|
||||
tp->snd_cwnd_stamp = tcp_time_stamp;
|
||||
|
||||
tp->bytes_acked = 0;
|
||||
tcp_clear_retrans_partial(tp);
|
||||
|
||||
if (tcp_is_reno(tp))
|
||||
@@ -3192,7 +3216,6 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
|
||||
TCP_ECN_queue_cwr(tp);
|
||||
}
|
||||
|
||||
tp->bytes_acked = 0;
|
||||
tp->snd_cwnd_cnt = 0;
|
||||
tp->prior_cwnd = tp->snd_cwnd;
|
||||
tp->prr_delivered = 0;
|
||||
@@ -3528,6 +3551,19 @@ static inline int tcp_may_update_window(const struct tcp_sock *tp,
|
||||
(ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd);
|
||||
}
|
||||
|
||||
/* If we update tp->snd_una, also update tp->bytes_acked */
|
||||
static void tcp_snd_una_update(struct tcp_sock *tp, u32 ack)
|
||||
{
|
||||
u32 delta = ack - tp->snd_una;
|
||||
|
||||
u64_stats_update_begin(&tp->syncp);
|
||||
tp->bytes_acked += delta;
|
||||
u64_stats_update_end(&tp->syncp);
|
||||
tp->snd_una = ack;
|
||||
}
|
||||
|
||||
u64_stats_update_begin(&tp->syncp);
|
||||
u64_stats_update_end(&tp->syncp);
|
||||
/* Update our send window.
|
||||
*
|
||||
* Window update algorithm, described in RFC793/RFC1122 (used in linux-2.2
|
||||
@@ -3563,7 +3599,7 @@ static int tcp_ack_update_window(struct sock *sk, const struct sk_buff *skb, u32
|
||||
}
|
||||
}
|
||||
|
||||
tp->snd_una = ack;
|
||||
tcp_snd_una_update(tp, ack);
|
||||
|
||||
return flag;
|
||||
}
|
||||
@@ -3575,7 +3611,6 @@ static void tcp_conservative_spur_to_response(struct tcp_sock *tp)
|
||||
{
|
||||
tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
|
||||
tp->snd_cwnd_cnt = 0;
|
||||
tp->bytes_acked = 0;
|
||||
TCP_ECN_queue_cwr(tp);
|
||||
tcp_moderate_cwnd(tp);
|
||||
}
|
||||
@@ -3766,7 +3801,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
|
||||
u32 ack_seq = TCP_SKB_CB(skb)->seq;
|
||||
u32 ack = TCP_SKB_CB(skb)->ack_seq;
|
||||
bool is_dupack = false;
|
||||
u32 prior_in_flight;
|
||||
u32 prior_in_flight, prior_cwnd = tp->snd_cwnd, prior_rtt = tp->srtt;
|
||||
u32 prior_fackets;
|
||||
int prior_packets = tp->packets_out;
|
||||
int prior_sacked = tp->sacked_out;
|
||||
@@ -3795,15 +3830,6 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
|
||||
if (after(ack, prior_snd_una))
|
||||
flag |= FLAG_SND_UNA_ADVANCED;
|
||||
|
||||
if (sysctl_tcp_abc) {
|
||||
if (icsk->icsk_ca_state < TCP_CA_CWR)
|
||||
tp->bytes_acked += ack - prior_snd_una;
|
||||
else if (icsk->icsk_ca_state == TCP_CA_Loss)
|
||||
/* we assume just one segment left network */
|
||||
tp->bytes_acked += min(ack - prior_snd_una,
|
||||
tp->mss_cache);
|
||||
}
|
||||
|
||||
prior_fackets = tp->fackets_out;
|
||||
prior_in_flight = tcp_packets_in_flight(tp);
|
||||
|
||||
@@ -3819,7 +3845,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
|
||||
* Note, we use the fact that SND.UNA>=SND.WL2.
|
||||
*/
|
||||
tcp_update_wl(tp, ack_seq);
|
||||
tp->snd_una = ack;
|
||||
tcp_snd_una_update(tp, ack);
|
||||
flag |= FLAG_WIN_UPDATE;
|
||||
|
||||
tcp_ca_event(sk, CA_EVENT_FAST_ACK);
|
||||
@@ -3879,6 +3905,8 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
|
||||
if ((flag & FLAG_FORWARD_PROGRESS) || !(flag & FLAG_NOT_DUP))
|
||||
dst_confirm(__sk_dst_get(sk));
|
||||
|
||||
if (tp->srtt != prior_rtt || tp->snd_cwnd != prior_cwnd)
|
||||
tcp_update_pacing_rate(sk);
|
||||
return 1;
|
||||
|
||||
no_queue:
|
||||
|
||||
@@ -1735,6 +1735,7 @@ process:
|
||||
}
|
||||
|
||||
bh_lock_sock_nested(sk);
|
||||
tcp_sk(sk)->segs_in += max_t(u16, 1, skb_shinfo(skb)->gso_segs);
|
||||
ret = 0;
|
||||
if (!sock_owned_by_user(sk)) {
|
||||
#ifdef CONFIG_NET_DMA
|
||||
@@ -1901,6 +1902,7 @@ static int tcp_v4_init_sock(struct sock *sk)
|
||||
skb_queue_head_init(&tp->out_of_order_queue);
|
||||
tcp_init_xmit_timers(sk);
|
||||
tcp_prequeue_init(tp);
|
||||
INIT_LIST_HEAD(&tp->tsq_node);
|
||||
|
||||
icsk->icsk_rto = TCP_TIMEOUT_INIT;
|
||||
tp->mdev = TCP_TIMEOUT_INIT;
|
||||
@@ -1918,6 +1920,7 @@ static int tcp_v4_init_sock(struct sock *sk)
|
||||
tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
|
||||
tp->snd_cwnd_clamp = ~0;
|
||||
tp->mss_cache = TCP_MSS_DEFAULT;
|
||||
u64_stats_init(&tp->syncp);
|
||||
|
||||
tp->reordering = sysctl_tcp_reordering;
|
||||
icsk->icsk_ca_ops = &tcp_init_congestion_ops;
|
||||
@@ -2645,6 +2648,7 @@ struct proto tcp_prot = {
|
||||
.sendmsg = tcp_sendmsg,
|
||||
.sendpage = tcp_sendpage,
|
||||
.backlog_rcv = tcp_v4_do_rcv,
|
||||
.release_cb = tcp_release_cb,
|
||||
.hash = inet_hash,
|
||||
.unhash = inet_unhash,
|
||||
.get_port = inet_csk_get_port,
|
||||
|
||||
@@ -464,12 +464,14 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
|
||||
|
||||
newtp->rcv_wup = newtp->copied_seq =
|
||||
newtp->rcv_nxt = treq->rcv_isn + 1;
|
||||
newtp->segs_in = 0;
|
||||
|
||||
newtp->snd_sml = newtp->snd_una =
|
||||
newtp->snd_nxt = newtp->snd_up =
|
||||
treq->snt_isn + 1 + tcp_s_data_size(oldtp);
|
||||
|
||||
tcp_prequeue_init(newtp);
|
||||
INIT_LIST_HEAD(&newtp->tsq_node);
|
||||
|
||||
tcp_init_wl(newtp, treq->rcv_isn);
|
||||
|
||||
@@ -490,7 +492,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
|
||||
*/
|
||||
newtp->snd_cwnd = TCP_INIT_CWND;
|
||||
newtp->snd_cwnd_cnt = 0;
|
||||
newtp->bytes_acked = 0;
|
||||
|
||||
newtp->frto_counter = 0;
|
||||
newtp->frto_highmark = 0;
|
||||
|
||||
+165
-2
@@ -48,6 +48,9 @@ int sysctl_tcp_retrans_collapse __read_mostly = 1;
|
||||
*/
|
||||
int sysctl_tcp_workaround_signed_windows __read_mostly = 0;
|
||||
|
||||
/* Default TSQ limit of two TSO segments */
|
||||
int sysctl_tcp_limit_output_bytes __read_mostly = 131072;
|
||||
|
||||
/* This limits the percentage of the congestion window which we
|
||||
* will allow a single TSO frame to consume. Building TSO frames
|
||||
* which are too large can cause TCP streams to be bursty.
|
||||
@@ -64,6 +67,8 @@ int sysctl_tcp_slow_start_after_idle __read_mostly = 1;
|
||||
int sysctl_tcp_cookie_size __read_mostly = 0; /* TCP_COOKIE_MAX */
|
||||
EXPORT_SYMBOL_GPL(sysctl_tcp_cookie_size);
|
||||
|
||||
static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
|
||||
int push_one, gfp_t gfp);
|
||||
|
||||
/* Account for new data that has been sent to the network. */
|
||||
static void tcp_event_new_data_sent(struct sock *sk, const struct sk_buff *skb)
|
||||
@@ -782,6 +787,140 @@ static unsigned tcp_established_options(struct sock *sk, struct sk_buff *skb,
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/* TCP SMALL QUEUES (TSQ)
|
||||
*
|
||||
* TSQ goal is to keep small amount of skbs per tcp flow in tx queues (qdisc+dev)
|
||||
* to reduce RTT and bufferbloat.
|
||||
* We do this using a special skb destructor (tcp_wfree).
|
||||
*
|
||||
* Its important tcp_wfree() can be replaced by sock_wfree() in the event skb
|
||||
* needs to be reallocated in a driver.
|
||||
* The invariant being skb->truesize substracted from sk->sk_wmem_alloc
|
||||
*
|
||||
* Since transmit from skb destructor is forbidden, we use a tasklet
|
||||
* to process all sockets that eventually need to send more skbs.
|
||||
* We use one tasklet per cpu, with its own queue of sockets.
|
||||
*/
|
||||
struct tsq_tasklet {
|
||||
struct tasklet_struct tasklet;
|
||||
struct list_head head; /* queue of tcp sockets */
|
||||
};
|
||||
static DEFINE_PER_CPU(struct tsq_tasklet, tsq_tasklet);
|
||||
|
||||
/*
|
||||
* One tasklest per cpu tries to send more skbs.
|
||||
* We run in tasklet context but need to disable irqs when
|
||||
* transfering tsq->head because tcp_wfree() might
|
||||
* interrupt us (non NAPI drivers)
|
||||
*/
|
||||
static void tcp_tasklet_func(unsigned long data)
|
||||
{
|
||||
struct tsq_tasklet *tsq = (struct tsq_tasklet *)data;
|
||||
LIST_HEAD(list);
|
||||
unsigned long flags;
|
||||
struct list_head *q, *n;
|
||||
struct tcp_sock *tp;
|
||||
struct sock *sk;
|
||||
|
||||
local_irq_save(flags);
|
||||
list_splice_init(&tsq->head, &list);
|
||||
local_irq_restore(flags);
|
||||
|
||||
list_for_each_safe(q, n, &list) {
|
||||
tp = list_entry(q, struct tcp_sock, tsq_node);
|
||||
list_del(&tp->tsq_node);
|
||||
|
||||
sk = (struct sock *)tp;
|
||||
bh_lock_sock(sk);
|
||||
|
||||
if (!sock_owned_by_user(sk)) {
|
||||
if ((1 << sk->sk_state) &
|
||||
(TCPF_ESTABLISHED | TCPF_FIN_WAIT1 |
|
||||
TCPF_CLOSING | TCPF_CLOSE_WAIT))
|
||||
tcp_write_xmit(sk,
|
||||
tcp_current_mss(sk),
|
||||
0, 0,
|
||||
GFP_ATOMIC);
|
||||
} else {
|
||||
/* defer the work to tcp_release_cb() */
|
||||
set_bit(TSQ_OWNED, &tp->tsq_flags);
|
||||
}
|
||||
bh_unlock_sock(sk);
|
||||
|
||||
clear_bit(TSQ_QUEUED, &tp->tsq_flags);
|
||||
sk_free(sk);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tcp_release_cb - tcp release_sock() callback
|
||||
* @sk: socket
|
||||
*
|
||||
* called from release_sock() to perform protocol dependent
|
||||
* actions before socket release.
|
||||
*/
|
||||
void tcp_release_cb(struct sock *sk)
|
||||
{
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
|
||||
if (test_and_clear_bit(TSQ_OWNED, &tp->tsq_flags)) {
|
||||
if ((1 << sk->sk_state) &
|
||||
(TCPF_ESTABLISHED | TCPF_FIN_WAIT1 |
|
||||
TCPF_CLOSING | TCPF_CLOSE_WAIT))
|
||||
tcp_write_xmit(sk,
|
||||
tcp_current_mss(sk),
|
||||
0, 0,
|
||||
GFP_ATOMIC);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(tcp_release_cb);
|
||||
|
||||
void __init tcp_tasklet_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct tsq_tasklet *tsq = &per_cpu(tsq_tasklet, i);
|
||||
|
||||
INIT_LIST_HEAD(&tsq->head);
|
||||
tasklet_init(&tsq->tasklet,
|
||||
tcp_tasklet_func,
|
||||
(unsigned long)tsq);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write buffer destructor automatically called from kfree_skb.
|
||||
* We cant xmit new skbs from this context, as we might already
|
||||
* hold qdisc lock.
|
||||
*/
|
||||
void tcp_wfree(struct sk_buff *skb)
|
||||
{
|
||||
struct sock *sk = skb->sk;
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
|
||||
if (test_and_clear_bit(TSQ_THROTTLED, &tp->tsq_flags) &&
|
||||
!test_and_set_bit(TSQ_QUEUED, &tp->tsq_flags)) {
|
||||
unsigned long flags;
|
||||
struct tsq_tasklet *tsq;
|
||||
|
||||
/* Keep a ref on socket.
|
||||
* This last ref will be released in tcp_tasklet_func()
|
||||
*/
|
||||
atomic_sub(skb->truesize - 1, &sk->sk_wmem_alloc);
|
||||
|
||||
/* queue this socket to tasklet queue */
|
||||
local_irq_save(flags);
|
||||
tsq = &__get_cpu_var(tsq_tasklet);
|
||||
list_add(&tp->tsq_node, &tsq->head);
|
||||
tasklet_schedule(&tsq->tasklet);
|
||||
local_irq_restore(flags);
|
||||
} else {
|
||||
sock_wfree(skb);
|
||||
}
|
||||
}
|
||||
|
||||
/* This routine actually transmits TCP packets queued in by
|
||||
* tcp_do_sendmsg(). This is used by both the initial
|
||||
* transmission and possible later retransmissions.
|
||||
@@ -845,7 +984,11 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
|
||||
|
||||
skb_push(skb, tcp_header_size);
|
||||
skb_reset_transport_header(skb);
|
||||
skb_set_owner_w(skb, sk);
|
||||
|
||||
skb_orphan(skb);
|
||||
skb->sk = sk;
|
||||
skb->destructor = tcp_wfree;
|
||||
atomic_add(skb->truesize, &sk->sk_wmem_alloc);
|
||||
|
||||
/* Build TCP header and checksum it. */
|
||||
th = tcp_hdr(skb);
|
||||
@@ -903,6 +1046,8 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
|
||||
TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS,
|
||||
tcp_skb_pcount(skb));
|
||||
|
||||
tp->segs_out += tcp_skb_pcount(skb);
|
||||
|
||||
err = icsk->icsk_af_ops->queue_xmit(skb, &inet->cork.fl);
|
||||
if (likely(err <= 0))
|
||||
return err;
|
||||
@@ -1567,7 +1712,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
|
||||
|
||||
/* If a full-sized TSO skb can be sent, do it. */
|
||||
if (limit >= min_t(unsigned int, sk->sk_gso_max_size,
|
||||
sk->sk_gso_max_segs * tp->mss_cache))
|
||||
tp->xmit_size_goal_segs * tp->mss_cache))
|
||||
goto send_now;
|
||||
|
||||
/* Middle in queue won't get any more data, full sendable already? */
|
||||
@@ -1793,6 +1938,24 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
|
||||
break;
|
||||
}
|
||||
|
||||
/* TCP Small Queues :
|
||||
* Control number of packets in qdisc/devices to two packets / or ~1 ms.
|
||||
* This allows for :
|
||||
* - better RTT estimation and ACK scheduling
|
||||
* - faster recovery
|
||||
* - high rates
|
||||
* Alas, some drivers / subsystems require a fair amount
|
||||
* of queued bytes to ensure line rate.
|
||||
* One example is wifi aggregation (802.11 AMPDU)
|
||||
*/
|
||||
limit = max_t(unsigned int, sysctl_tcp_limit_output_bytes,
|
||||
sk->sk_pacing_rate >> 10);
|
||||
|
||||
if (atomic_read(&sk->sk_wmem_alloc) > limit) {
|
||||
set_bit(TSQ_THROTTLED, &tp->tsq_flags);
|
||||
break;
|
||||
}
|
||||
|
||||
limit = mss_now;
|
||||
if (tso_segs > 1 && !tcp_urg_mode(tp))
|
||||
limit = tcp_mss_split_point(sk, skb, mss_now,
|
||||
|
||||
@@ -296,10 +296,24 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp,
|
||||
|
||||
static int snmp6_alloc_dev(struct inet6_dev *idev)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (snmp_mib_init((void __percpu **)idev->stats.ipv6,
|
||||
sizeof(struct ipstats_mib),
|
||||
__alignof__(struct ipstats_mib)) < 0)
|
||||
goto err_ip;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct ipstats_mib *addrconf_stats;
|
||||
addrconf_stats = per_cpu_ptr(idev->stats.ipv6[0], i);
|
||||
u64_stats_init(&addrconf_stats->syncp);
|
||||
#if SNMP_ARRAY_SZ == 2
|
||||
addrconf_stats = per_cpu_ptr(idev->stats.ipv6[1], i);
|
||||
u64_stats_init(&addrconf_stats->syncp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
idev->stats.icmpv6dev = kzalloc(sizeof(struct icmpv6_mib_device),
|
||||
GFP_KERNEL);
|
||||
if (!idev->stats.icmpv6dev)
|
||||
|
||||
@@ -1019,6 +1019,8 @@ static void ipv6_packet_cleanup(void)
|
||||
|
||||
static int __net_init ipv6_init_mibs(struct net *net)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (snmp_mib_init((void __percpu **)net->mib.udp_stats_in6,
|
||||
sizeof(struct udp_mib),
|
||||
__alignof__(struct udp_mib)) < 0)
|
||||
@@ -1031,6 +1033,18 @@ static int __net_init ipv6_init_mibs(struct net *net)
|
||||
sizeof(struct ipstats_mib),
|
||||
__alignof__(struct ipstats_mib)) < 0)
|
||||
goto err_ip_mib;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct ipstats_mib *af_inet6_stats;
|
||||
af_inet6_stats = per_cpu_ptr(net->mib.ipv6_statistics[0], i);
|
||||
u64_stats_init(&af_inet6_stats->syncp);
|
||||
#if SNMP_ARRAY_SZ == 2
|
||||
af_inet6_stats = per_cpu_ptr(net->mib.ipv6_statistics[1], i);
|
||||
u64_stats_init(&af_inet6_stats->syncp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (snmp_mib_init((void __percpu **)net->mib.icmpv6_statistics,
|
||||
sizeof(struct icmpv6_mib),
|
||||
__alignof__(struct icmpv6_mib)) < 0)
|
||||
|
||||
+23
-5
@@ -98,16 +98,25 @@ struct pcpu_tstats {
|
||||
|
||||
static struct net_device_stats *ip6_get_stats(struct net_device *dev)
|
||||
{
|
||||
struct pcpu_tstats sum = { 0 };
|
||||
struct pcpu_tstats tmp, sum = { 0 };
|
||||
int i;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
unsigned int start;
|
||||
const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
|
||||
|
||||
sum.rx_packets += tstats->rx_packets;
|
||||
sum.rx_bytes += tstats->rx_bytes;
|
||||
sum.tx_packets += tstats->tx_packets;
|
||||
sum.tx_bytes += tstats->tx_bytes;
|
||||
do {
|
||||
start = u64_stats_fetch_begin_irq(&tstats->syncp);
|
||||
tmp.rx_packets = tstats->rx_packets;
|
||||
tmp.rx_bytes = tstats->rx_bytes;
|
||||
tmp.tx_packets = tstats->tx_packets;
|
||||
tmp.tx_bytes = tstats->tx_bytes;
|
||||
} while (u64_stats_fetch_retry_irq(&tstats->syncp, start));
|
||||
|
||||
sum.rx_packets += tmp.rx_packets;
|
||||
sum.rx_bytes += tmp.rx_bytes;
|
||||
sum.tx_packets += tmp.tx_packets;
|
||||
sum.tx_bytes += tmp.tx_bytes;
|
||||
}
|
||||
dev->stats.rx_packets = sum.rx_packets;
|
||||
dev->stats.rx_bytes = sum.rx_bytes;
|
||||
@@ -761,8 +770,10 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
|
||||
memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
|
||||
|
||||
tstats = this_cpu_ptr(t->dev->tstats);
|
||||
u64_stats_update_begin(&tstats->syncp);
|
||||
tstats->rx_packets++;
|
||||
tstats->rx_bytes += skb->len;
|
||||
u64_stats_update_end(&tstats->syncp);
|
||||
|
||||
__skb_tunnel_rx(skb, t->dev);
|
||||
|
||||
@@ -1408,11 +1419,18 @@ static inline int
|
||||
ip6_tnl_dev_init_gen(struct net_device *dev)
|
||||
{
|
||||
struct ip6_tnl *t = netdev_priv(dev);
|
||||
int i;
|
||||
|
||||
t->dev = dev;
|
||||
dev->tstats = alloc_percpu(struct pcpu_tstats);
|
||||
if (!dev->tstats)
|
||||
return -ENOMEM;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct pcpu_tstats *ip6_tnl_stats;
|
||||
ip6_tnl_stats = per_cpu_ptr(dev->tstats, i);
|
||||
u64_stats_init(&ip6_tnl_stats->syncp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+50
-17
@@ -87,31 +87,47 @@ struct sit_net {
|
||||
|
||||
/* often modified stats are per cpu, other are shared (netdev->stats) */
|
||||
struct pcpu_tstats {
|
||||
unsigned long rx_packets;
|
||||
unsigned long rx_bytes;
|
||||
unsigned long tx_packets;
|
||||
unsigned long tx_bytes;
|
||||
} __attribute__((aligned(4*sizeof(unsigned long))));
|
||||
u64 rx_packets;
|
||||
u64 rx_bytes;
|
||||
u64 tx_packets;
|
||||
u64 tx_bytes;
|
||||
struct u64_stats_sync syncp;
|
||||
};
|
||||
|
||||
static struct net_device_stats *ipip6_get_stats(struct net_device *dev)
|
||||
static struct rtnl_link_stats64 *ipip6_get_stats64(struct net_device *dev,
|
||||
struct rtnl_link_stats64 *tot)
|
||||
{
|
||||
struct pcpu_tstats sum = { 0 };
|
||||
int i;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
|
||||
u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
|
||||
unsigned int start;
|
||||
|
||||
sum.rx_packets += tstats->rx_packets;
|
||||
sum.rx_bytes += tstats->rx_bytes;
|
||||
sum.tx_packets += tstats->tx_packets;
|
||||
sum.tx_bytes += tstats->tx_bytes;
|
||||
do {
|
||||
start = u64_stats_fetch_begin_irq(&tstats->syncp);
|
||||
rx_packets = tstats->rx_packets;
|
||||
tx_packets = tstats->tx_packets;
|
||||
rx_bytes = tstats->rx_bytes;
|
||||
tx_bytes = tstats->tx_bytes;
|
||||
} while (u64_stats_fetch_retry_irq(&tstats->syncp, start));
|
||||
|
||||
tot->rx_packets += rx_packets;
|
||||
tot->tx_packets += tx_packets;
|
||||
tot->rx_bytes += rx_bytes;
|
||||
tot->tx_bytes += tx_bytes;
|
||||
}
|
||||
dev->stats.rx_packets = sum.rx_packets;
|
||||
dev->stats.rx_bytes = sum.rx_bytes;
|
||||
dev->stats.tx_packets = sum.tx_packets;
|
||||
dev->stats.tx_bytes = sum.tx_bytes;
|
||||
return &dev->stats;
|
||||
|
||||
tot->rx_errors = dev->stats.rx_errors;
|
||||
tot->tx_fifo_errors = dev->stats.tx_fifo_errors;
|
||||
tot->tx_carrier_errors = dev->stats.tx_carrier_errors;
|
||||
tot->tx_dropped = dev->stats.tx_dropped;
|
||||
tot->tx_aborted_errors = dev->stats.tx_aborted_errors;
|
||||
tot->tx_errors = dev->stats.tx_errors;
|
||||
|
||||
return tot;
|
||||
}
|
||||
|
||||
/*
|
||||
* Must be invoked with rcu_read_lock
|
||||
*/
|
||||
@@ -588,8 +604,10 @@ static int ipip6_rcv(struct sk_buff *skb)
|
||||
}
|
||||
|
||||
tstats = this_cpu_ptr(tunnel->dev->tstats);
|
||||
u64_stats_update_begin(&tstats->syncp);
|
||||
tstats->rx_packets++;
|
||||
tstats->rx_bytes += skb->len;
|
||||
u64_stats_update_end(&tstats->syncp);
|
||||
|
||||
__skb_tunnel_rx(skb, tunnel->dev);
|
||||
|
||||
@@ -1126,7 +1144,7 @@ static const struct net_device_ops ipip6_netdev_ops = {
|
||||
.ndo_start_xmit = ipip6_tunnel_xmit,
|
||||
.ndo_do_ioctl = ipip6_tunnel_ioctl,
|
||||
.ndo_change_mtu = ipip6_tunnel_change_mtu,
|
||||
.ndo_get_stats = ipip6_get_stats,
|
||||
.ndo_get_stats64= ipip6_get_stats64,
|
||||
};
|
||||
|
||||
static void ipip6_dev_free(struct net_device *dev)
|
||||
@@ -1154,6 +1172,7 @@ static void ipip6_tunnel_setup(struct net_device *dev)
|
||||
static int ipip6_tunnel_init(struct net_device *dev)
|
||||
{
|
||||
struct ip_tunnel *tunnel = netdev_priv(dev);
|
||||
int i;
|
||||
|
||||
tunnel->dev = dev;
|
||||
|
||||
@@ -1165,6 +1184,12 @@ static int ipip6_tunnel_init(struct net_device *dev)
|
||||
if (!dev->tstats)
|
||||
return -ENOMEM;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct pcpu_tstats *ipip6_tunnel_stats;
|
||||
ipip6_tunnel_stats = per_cpu_ptr(dev->tstats, i);
|
||||
u64_stats_init(&ipip6_tunnel_stats->syncp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1174,6 +1199,7 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev)
|
||||
struct iphdr *iph = &tunnel->parms.iph;
|
||||
struct net *net = dev_net(dev);
|
||||
struct sit_net *sitn = net_generic(net, sit_net_id);
|
||||
int i;
|
||||
|
||||
tunnel->dev = dev;
|
||||
strcpy(tunnel->parms.name, dev->name);
|
||||
@@ -1186,6 +1212,13 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev)
|
||||
dev->tstats = alloc_percpu(struct pcpu_tstats);
|
||||
if (!dev->tstats)
|
||||
return -ENOMEM;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct pcpu_tstats *ipip6_fb_stats;
|
||||
ipip6_fb_stats = per_cpu_ptr(dev->tstats, i);
|
||||
u64_stats_init(&ipip6_fb_stats->syncp);
|
||||
}
|
||||
|
||||
dev_hold(dev);
|
||||
rcu_assign_pointer(sitn->tunnels_wc[0], tunnel);
|
||||
return 0;
|
||||
|
||||
@@ -1656,6 +1656,7 @@ process:
|
||||
}
|
||||
|
||||
bh_lock_sock_nested(sk);
|
||||
tcp_sk(sk)->segs_in += max_t(u16, 1, skb_shinfo(skb)->gso_segs);
|
||||
ret = 0;
|
||||
if (!sock_owned_by_user(sk)) {
|
||||
#ifdef CONFIG_NET_DMA
|
||||
@@ -1851,6 +1852,7 @@ static int tcp_v6_init_sock(struct sock *sk)
|
||||
skb_queue_head_init(&tp->out_of_order_queue);
|
||||
tcp_init_xmit_timers(sk);
|
||||
tcp_prequeue_init(tp);
|
||||
INIT_LIST_HEAD(&tp->tsq_node);
|
||||
|
||||
icsk->icsk_rto = TCP_TIMEOUT_INIT;
|
||||
tp->mdev = TCP_TIMEOUT_INIT;
|
||||
@@ -2118,6 +2120,7 @@ struct proto tcpv6_prot = {
|
||||
.sendmsg = tcp_sendmsg,
|
||||
.sendpage = tcp_sendpage,
|
||||
.backlog_rcv = tcp_v6_do_rcv,
|
||||
.release_cb = tcp_release_cb,
|
||||
.hash = tcp_v6_hash,
|
||||
.unhash = inet_unhash,
|
||||
.get_port = inet_csk_get_port,
|
||||
|
||||
@@ -842,7 +842,7 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest,
|
||||
struct ip_vs_dest **dest_p)
|
||||
{
|
||||
struct ip_vs_dest *dest;
|
||||
unsigned atype;
|
||||
unsigned int atype, i;
|
||||
|
||||
EnterFunction(2);
|
||||
|
||||
@@ -869,6 +869,12 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest,
|
||||
if (!dest->stats.cpustats)
|
||||
goto err_alloc;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct ip_vs_cpu_stats *ip_vs_dest_stats;
|
||||
ip_vs_dest_stats = per_cpu_ptr(dest->stats.cpustats, i);
|
||||
u64_stats_init(&ip_vs_dest_stats->syncp);
|
||||
}
|
||||
|
||||
dest->af = svc->af;
|
||||
dest->protocol = svc->protocol;
|
||||
dest->vaddr = svc->addr;
|
||||
@@ -1130,7 +1136,7 @@ static int
|
||||
ip_vs_add_service(struct net *net, struct ip_vs_service_user_kern *u,
|
||||
struct ip_vs_service **svc_p)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = 0, i;
|
||||
struct ip_vs_scheduler *sched = NULL;
|
||||
struct ip_vs_pe *pe = NULL;
|
||||
struct ip_vs_service *svc = NULL;
|
||||
@@ -1174,6 +1180,12 @@ ip_vs_add_service(struct net *net, struct ip_vs_service_user_kern *u,
|
||||
if (!svc->stats.cpustats)
|
||||
goto out_err;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct ip_vs_cpu_stats *ip_vs_stats;
|
||||
ip_vs_stats = per_cpu_ptr(svc->stats.cpustats, i);
|
||||
u64_stats_init(&ip_vs_stats->syncp);
|
||||
}
|
||||
|
||||
/* I'm the first user of the service */
|
||||
atomic_set(&svc->usecnt, 0);
|
||||
atomic_set(&svc->refcnt, 0);
|
||||
@@ -2131,10 +2143,10 @@ static int ip_vs_stats_percpu_show(struct seq_file *seq, void *v)
|
||||
__u64 inbytes, outbytes;
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&u->syncp);
|
||||
start = u64_stats_fetch_begin_irq(&u->syncp);
|
||||
inbytes = u->ustats.inbytes;
|
||||
outbytes = u->ustats.outbytes;
|
||||
} while (u64_stats_fetch_retry_bh(&u->syncp, start));
|
||||
} while (u64_stats_fetch_retry_irq(&u->syncp, start));
|
||||
|
||||
seq_printf(seq, "%3X %8X %8X %8X %16LX %16LX\n",
|
||||
i, u->ustats.conns, u->ustats.inpkts,
|
||||
@@ -3625,7 +3637,7 @@ static void ip_vs_genl_unregister(void)
|
||||
#ifdef CONFIG_SYSCTL
|
||||
int __net_init ip_vs_control_net_init_sysctl(struct net *net)
|
||||
{
|
||||
int idx;
|
||||
int i, idx;
|
||||
struct netns_ipvs *ipvs = net_ipvs(net);
|
||||
struct ctl_table *tbl;
|
||||
|
||||
@@ -3725,6 +3737,12 @@ int __net_init ip_vs_control_net_init(struct net *net)
|
||||
if (!ipvs->tot_stats.cpustats)
|
||||
return -ENOMEM;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct ip_vs_cpu_stats *ipvs_tot_stats;
|
||||
ipvs_tot_stats = per_cpu_ptr(ipvs->tot_stats.cpustats, i);
|
||||
u64_stats_init(&ipvs_tot_stats->syncp);
|
||||
}
|
||||
|
||||
spin_lock_init(&ipvs->tot_stats.lock);
|
||||
|
||||
proc_net_fops_create(net, "ip_vs", 0, &ip_vs_info_fops);
|
||||
|
||||
@@ -722,9 +722,9 @@ static void get_dp_stats(struct datapath *dp, struct ovs_dp_stats *stats)
|
||||
percpu_stats = per_cpu_ptr(dp->stats_percpu, i);
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&percpu_stats->sync);
|
||||
start = u64_stats_fetch_begin_irq(&percpu_stats->sync);
|
||||
local_stats = *percpu_stats;
|
||||
} while (u64_stats_fetch_retry_bh(&percpu_stats->sync, start));
|
||||
} while (u64_stats_fetch_retry_irq(&percpu_stats->sync, start));
|
||||
|
||||
stats->n_hit += local_stats.n_hit;
|
||||
stats->n_missed += local_stats.n_missed;
|
||||
@@ -1261,6 +1261,12 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
|
||||
goto err_destroy_table;
|
||||
}
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct dp_stats_percpu *dpath_stats;
|
||||
dpath_stats = per_cpu_ptr(dp->stats_percpu, i);
|
||||
u64_stats_init(&dpath_stats->sync);
|
||||
}
|
||||
|
||||
/* Set up our datapath device. */
|
||||
parms.name = nla_data(a[OVS_DP_ATTR_NAME]);
|
||||
parms.type = OVS_VPORT_TYPE_INTERNAL;
|
||||
|
||||
+10
-2
@@ -109,6 +109,7 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops,
|
||||
{
|
||||
struct vport *vport;
|
||||
size_t alloc_size;
|
||||
int i;
|
||||
|
||||
alloc_size = sizeof(struct vport);
|
||||
if (priv_size) {
|
||||
@@ -131,6 +132,13 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops,
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct pcpu_tstats *vport_stats;
|
||||
vport_stats = per_cpu_ptr(vport->percpu_stats, i);
|
||||
u64_stats_init(&vport_stats->syncp);
|
||||
}
|
||||
|
||||
|
||||
spin_lock_init(&vport->stats_lock);
|
||||
|
||||
return vport;
|
||||
@@ -265,9 +273,9 @@ void ovs_vport_get_stats(struct vport *vport, struct ovs_vport_stats *stats)
|
||||
percpu_stats = per_cpu_ptr(vport->percpu_stats, i);
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&percpu_stats->sync);
|
||||
start = u64_stats_fetch_begin_irq(&percpu_stats->sync);
|
||||
local_stats = *percpu_stats;
|
||||
} while (u64_stats_fetch_retry_bh(&percpu_stats->sync, start));
|
||||
} while (u64_stats_fetch_retry_irq(&percpu_stats->sync, start));
|
||||
|
||||
stats->rx_bytes += local_stats.rx_bytes;
|
||||
stats->rx_packets += local_stats.rx_packets;
|
||||
|
||||
Reference in New Issue
Block a user