On Wed, 2016-09-28 at 12:52 +0200, Paolo Abeni wrote:
quoted hunk ↗ jump to hunk
+static void udp_rmem_release(struct sock *sk, int partial)
+{
+ struct udp_sock *up = udp_sk(sk);
+ int fwd, amt;
+
+ if (partial && !udp_under_memory_pressure(sk))
+ return;
+
+ /* we can have concurrent release; if we catch any conflict
+ * we let only one of them do the work
+ */
+ if (atomic_dec_if_positive(&up->can_reclaim) < 0)
+ return;
+
+ fwd = __udp_forward(up, atomic_read(&sk->sk_rmem_alloc));
+ if (fwd < SK_MEM_QUANTUM + partial) {
+ atomic_inc(&up->can_reclaim);
+ return;
+ }
+
+ amt = (fwd - partial) & ~(SK_MEM_QUANTUM - 1);
+ atomic_sub(amt, &up->mem_allocated);
+ atomic_inc(&up->can_reclaim);
+
+ __sk_mem_reduce_allocated(sk, amt >> SK_MEM_QUANTUM_SHIFT);
+ sk->sk_forward_alloc = fwd - amt;
+}
This is racy... all these atomics make me nervous...