18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* ar-skbuff.c: socket buffer destruction handling 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 58c2ecf20Sopenharmony_ci * Written by David Howells (dhowells@redhat.com) 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/module.h> 118c2ecf20Sopenharmony_ci#include <linux/net.h> 128c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 138c2ecf20Sopenharmony_ci#include <net/sock.h> 148c2ecf20Sopenharmony_ci#include <net/af_rxrpc.h> 158c2ecf20Sopenharmony_ci#include "ar-internal.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#define is_tx_skb(skb) (rxrpc_skb(skb)->rx_flags & RXRPC_SKB_TX_BUFFER) 188c2ecf20Sopenharmony_ci#define select_skb_count(skb) (is_tx_skb(skb) ? &rxrpc_n_tx_skbs : &rxrpc_n_rx_skbs) 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci/* 218c2ecf20Sopenharmony_ci * Note the allocation or reception of a socket buffer. 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_civoid rxrpc_new_skb(struct sk_buff *skb, enum rxrpc_skb_trace op) 248c2ecf20Sopenharmony_ci{ 258c2ecf20Sopenharmony_ci const void *here = __builtin_return_address(0); 268c2ecf20Sopenharmony_ci int n = atomic_inc_return(select_skb_count(skb)); 278c2ecf20Sopenharmony_ci trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, 288c2ecf20Sopenharmony_ci rxrpc_skb(skb)->rx_flags, here); 298c2ecf20Sopenharmony_ci} 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci/* 328c2ecf20Sopenharmony_ci * Note the re-emergence of a socket buffer from a queue or buffer. 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_civoid rxrpc_see_skb(struct sk_buff *skb, enum rxrpc_skb_trace op) 358c2ecf20Sopenharmony_ci{ 368c2ecf20Sopenharmony_ci const void *here = __builtin_return_address(0); 378c2ecf20Sopenharmony_ci if (skb) { 388c2ecf20Sopenharmony_ci int n = atomic_read(select_skb_count(skb)); 398c2ecf20Sopenharmony_ci trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, 408c2ecf20Sopenharmony_ci rxrpc_skb(skb)->rx_flags, here); 418c2ecf20Sopenharmony_ci } 428c2ecf20Sopenharmony_ci} 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci/* 458c2ecf20Sopenharmony_ci * Note the addition of a ref on a socket buffer. 468c2ecf20Sopenharmony_ci */ 478c2ecf20Sopenharmony_civoid rxrpc_get_skb(struct sk_buff *skb, enum rxrpc_skb_trace op) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci const void *here = __builtin_return_address(0); 508c2ecf20Sopenharmony_ci int n = atomic_inc_return(select_skb_count(skb)); 518c2ecf20Sopenharmony_ci trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, 528c2ecf20Sopenharmony_ci rxrpc_skb(skb)->rx_flags, here); 538c2ecf20Sopenharmony_ci skb_get(skb); 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci/* 578c2ecf20Sopenharmony_ci * Note the dropping of a ref on a socket buffer by the core. 588c2ecf20Sopenharmony_ci */ 598c2ecf20Sopenharmony_civoid rxrpc_eaten_skb(struct sk_buff *skb, enum rxrpc_skb_trace op) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci const void *here = __builtin_return_address(0); 628c2ecf20Sopenharmony_ci int n = atomic_inc_return(&rxrpc_n_rx_skbs); 638c2ecf20Sopenharmony_ci trace_rxrpc_skb(skb, op, 0, n, 0, here); 648c2ecf20Sopenharmony_ci} 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci/* 678c2ecf20Sopenharmony_ci * Note the destruction of a socket buffer. 688c2ecf20Sopenharmony_ci */ 698c2ecf20Sopenharmony_civoid rxrpc_free_skb(struct sk_buff *skb, enum rxrpc_skb_trace op) 708c2ecf20Sopenharmony_ci{ 718c2ecf20Sopenharmony_ci const void *here = __builtin_return_address(0); 728c2ecf20Sopenharmony_ci if (skb) { 738c2ecf20Sopenharmony_ci int n; 748c2ecf20Sopenharmony_ci n = atomic_dec_return(select_skb_count(skb)); 758c2ecf20Sopenharmony_ci trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, 768c2ecf20Sopenharmony_ci rxrpc_skb(skb)->rx_flags, here); 778c2ecf20Sopenharmony_ci kfree_skb(skb); 788c2ecf20Sopenharmony_ci } 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci/* 828c2ecf20Sopenharmony_ci * Clear a queue of socket buffers. 838c2ecf20Sopenharmony_ci */ 848c2ecf20Sopenharmony_civoid rxrpc_purge_queue(struct sk_buff_head *list) 858c2ecf20Sopenharmony_ci{ 868c2ecf20Sopenharmony_ci const void *here = __builtin_return_address(0); 878c2ecf20Sopenharmony_ci struct sk_buff *skb; 888c2ecf20Sopenharmony_ci while ((skb = skb_dequeue((list))) != NULL) { 898c2ecf20Sopenharmony_ci int n = atomic_dec_return(select_skb_count(skb)); 908c2ecf20Sopenharmony_ci trace_rxrpc_skb(skb, rxrpc_skb_purged, 918c2ecf20Sopenharmony_ci refcount_read(&skb->users), n, 928c2ecf20Sopenharmony_ci rxrpc_skb(skb)->rx_flags, here); 938c2ecf20Sopenharmony_ci kfree_skb(skb); 948c2ecf20Sopenharmony_ci } 958c2ecf20Sopenharmony_ci} 96