|
@@ -320,17 +320,36 @@ struct tcp_splice_state {
|
|
|
* All the __sk_mem_schedule() is of this nature: accounting
|
|
|
* is strict, actions are advisory and have some latency.
|
|
|
*/
|
|
|
-int tcp_memory_pressure __read_mostly;
|
|
|
-EXPORT_SYMBOL(tcp_memory_pressure);
|
|
|
+unsigned long tcp_memory_pressure __read_mostly;
|
|
|
+EXPORT_SYMBOL_GPL(tcp_memory_pressure);
|
|
|
|
|
|
void tcp_enter_memory_pressure(struct sock *sk)
|
|
|
{
|
|
|
- if (!tcp_memory_pressure) {
|
|
|
+ unsigned long val;
|
|
|
+
|
|
|
+ if (tcp_memory_pressure)
|
|
|
+ return;
|
|
|
+ val = jiffies;
|
|
|
+
|
|
|
+ if (!val)
|
|
|
+ val--;
|
|
|
+ if (!cmpxchg(&tcp_memory_pressure, 0, val))
|
|
|
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMEMORYPRESSURES);
|
|
|
- tcp_memory_pressure = 1;
|
|
|
- }
|
|
|
}
|
|
|
-EXPORT_SYMBOL(tcp_enter_memory_pressure);
|
|
|
+EXPORT_SYMBOL_GPL(tcp_enter_memory_pressure);
|
|
|
+
|
|
|
+void tcp_leave_memory_pressure(struct sock *sk)
|
|
|
+{
|
|
|
+ unsigned long val;
|
|
|
+
|
|
|
+ if (!tcp_memory_pressure)
|
|
|
+ return;
|
|
|
+ val = xchg(&tcp_memory_pressure, 0);
|
|
|
+ if (val)
|
|
|
+ NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPMEMORYPRESSURESCHRONO,
|
|
|
+ jiffies_to_msecs(jiffies - val));
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(tcp_leave_memory_pressure);
|
|
|
|
|
|
/* Convert seconds to retransmits based on initial and max timeout */
|
|
|
static u8 secs_to_retrans(int seconds, int timeout, int rto_max)
|