162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/* Socket buffer accounting
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
562306a36Sopenharmony_ci * Written by David Howells (dhowells@redhat.com)
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/module.h>
1162306a36Sopenharmony_ci#include <linux/net.h>
1262306a36Sopenharmony_ci#include <linux/skbuff.h>
1362306a36Sopenharmony_ci#include <net/sock.h>
1462306a36Sopenharmony_ci#include <net/af_rxrpc.h>
1562306a36Sopenharmony_ci#include "ar-internal.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#define select_skb_count(skb) (&rxrpc_n_rx_skbs)
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci/*
2062306a36Sopenharmony_ci * Note the allocation or reception of a socket buffer.
2162306a36Sopenharmony_ci */
2262306a36Sopenharmony_civoid rxrpc_new_skb(struct sk_buff *skb, enum rxrpc_skb_trace why)
2362306a36Sopenharmony_ci{
2462306a36Sopenharmony_ci	int n = atomic_inc_return(select_skb_count(skb));
2562306a36Sopenharmony_ci	trace_rxrpc_skb(skb, refcount_read(&skb->users), n, why);
2662306a36Sopenharmony_ci}
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/*
2962306a36Sopenharmony_ci * Note the re-emergence of a socket buffer from a queue or buffer.
3062306a36Sopenharmony_ci */
3162306a36Sopenharmony_civoid rxrpc_see_skb(struct sk_buff *skb, enum rxrpc_skb_trace why)
3262306a36Sopenharmony_ci{
3362306a36Sopenharmony_ci	if (skb) {
3462306a36Sopenharmony_ci		int n = atomic_read(select_skb_count(skb));
3562306a36Sopenharmony_ci		trace_rxrpc_skb(skb, refcount_read(&skb->users), n, why);
3662306a36Sopenharmony_ci	}
3762306a36Sopenharmony_ci}
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/*
4062306a36Sopenharmony_ci * Note the addition of a ref on a socket buffer.
4162306a36Sopenharmony_ci */
4262306a36Sopenharmony_civoid rxrpc_get_skb(struct sk_buff *skb, enum rxrpc_skb_trace why)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	int n = atomic_inc_return(select_skb_count(skb));
4562306a36Sopenharmony_ci	trace_rxrpc_skb(skb, refcount_read(&skb->users), n, why);
4662306a36Sopenharmony_ci	skb_get(skb);
4762306a36Sopenharmony_ci}
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci/*
5062306a36Sopenharmony_ci * Note the dropping of a ref on a socket buffer by the core.
5162306a36Sopenharmony_ci */
5262306a36Sopenharmony_civoid rxrpc_eaten_skb(struct sk_buff *skb, enum rxrpc_skb_trace why)
5362306a36Sopenharmony_ci{
5462306a36Sopenharmony_ci	int n = atomic_inc_return(&rxrpc_n_rx_skbs);
5562306a36Sopenharmony_ci	trace_rxrpc_skb(skb, 0, n, why);
5662306a36Sopenharmony_ci}
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci/*
5962306a36Sopenharmony_ci * Note the destruction of a socket buffer.
6062306a36Sopenharmony_ci */
6162306a36Sopenharmony_civoid rxrpc_free_skb(struct sk_buff *skb, enum rxrpc_skb_trace why)
6262306a36Sopenharmony_ci{
6362306a36Sopenharmony_ci	if (skb) {
6462306a36Sopenharmony_ci		int n = atomic_dec_return(select_skb_count(skb));
6562306a36Sopenharmony_ci		trace_rxrpc_skb(skb, refcount_read(&skb->users), n, why);
6662306a36Sopenharmony_ci		consume_skb(skb);
6762306a36Sopenharmony_ci	}
6862306a36Sopenharmony_ci}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci/*
7162306a36Sopenharmony_ci * Clear a queue of socket buffers.
7262306a36Sopenharmony_ci */
7362306a36Sopenharmony_civoid rxrpc_purge_queue(struct sk_buff_head *list)
7462306a36Sopenharmony_ci{
7562306a36Sopenharmony_ci	struct sk_buff *skb;
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	while ((skb = skb_dequeue((list))) != NULL) {
7862306a36Sopenharmony_ci		int n = atomic_dec_return(select_skb_count(skb));
7962306a36Sopenharmony_ci		trace_rxrpc_skb(skb, refcount_read(&skb->users), n,
8062306a36Sopenharmony_ci				rxrpc_skb_put_purge);
8162306a36Sopenharmony_ci		consume_skb(skb);
8262306a36Sopenharmony_ci	}
8362306a36Sopenharmony_ci}
84