mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
can: use skb hash instead of private variable in headroom
The can_skb_priv::skbcnt variable is used to identify CAN skbs in the RX path analogue to the skb->hash. As the skb hash is not filled in CAN skbs move the private skbcnt value to skb->hash and set skb->sw_hash accordingly. The skb->hash is a value used for RPS to identify skbs. Use it as intended. Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net> Link: https://patch.msgid.link/20260201-can_skb_ext-v8-1-3635d790fe8b@hartkopp.net Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
committed by
Paolo Abeni
parent
0cbcc0fdce
commit
d4fb6514ff
@@ -202,7 +202,6 @@ static void init_can_skb_reserve(struct sk_buff *skb)
|
||||
skb_reset_transport_header(skb);
|
||||
|
||||
can_skb_reserve(skb);
|
||||
can_skb_prv(skb)->skbcnt = 0;
|
||||
}
|
||||
|
||||
struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
|
||||
@@ -312,7 +311,6 @@ static bool can_skb_headroom_valid(struct net_device *dev, struct sk_buff *skb)
|
||||
if (skb->ip_summed == CHECKSUM_NONE) {
|
||||
/* init headroom */
|
||||
can_skb_prv(skb)->ifindex = dev->ifindex;
|
||||
can_skb_prv(skb)->skbcnt = 0;
|
||||
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ extern void can_rx_unregister(struct net *net, struct net_device *dev,
|
||||
void *data);
|
||||
|
||||
extern int can_send(struct sk_buff *skb, int loop);
|
||||
void can_set_skb_uid(struct sk_buff *skb);
|
||||
void can_sock_destruct(struct sock *sk);
|
||||
|
||||
#endif /* !_CAN_CORE_H */
|
||||
|
||||
@@ -49,13 +49,11 @@ bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb);
|
||||
/**
|
||||
* struct can_skb_priv - private additional data inside CAN sk_buffs
|
||||
* @ifindex: ifindex of the first interface the CAN frame appeared on
|
||||
* @skbcnt: atomic counter to have an unique id together with skb pointer
|
||||
* @frame_len: length of CAN frame in data link layer
|
||||
* @cf: align to the following CAN frame at skb->data
|
||||
*/
|
||||
struct can_skb_priv {
|
||||
int ifindex;
|
||||
int skbcnt;
|
||||
unsigned int frame_len;
|
||||
struct can_frame cf[];
|
||||
};
|
||||
|
||||
@@ -641,6 +641,16 @@ static int can_rcv_filter(struct can_dev_rcv_lists *dev_rcv_lists, struct sk_buf
|
||||
return matches;
|
||||
}
|
||||
|
||||
void can_set_skb_uid(struct sk_buff *skb)
|
||||
{
|
||||
/* create non-zero unique skb identifier together with *skb */
|
||||
while (!(skb->hash))
|
||||
skb->hash = atomic_inc_return(&skbcounter);
|
||||
|
||||
skb->sw_hash = 1;
|
||||
}
|
||||
EXPORT_SYMBOL(can_set_skb_uid);
|
||||
|
||||
static void can_receive(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct can_dev_rcv_lists *dev_rcv_lists;
|
||||
@@ -652,9 +662,7 @@ static void can_receive(struct sk_buff *skb, struct net_device *dev)
|
||||
atomic_long_inc(&pkg_stats->rx_frames);
|
||||
atomic_long_inc(&pkg_stats->rx_frames_delta);
|
||||
|
||||
/* create non-zero unique skb identifier together with *skb */
|
||||
while (!(can_skb_prv(skb)->skbcnt))
|
||||
can_skb_prv(skb)->skbcnt = atomic_inc_return(&skbcounter);
|
||||
can_set_skb_uid(skb);
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
|
||||
@@ -316,7 +316,6 @@ static void bcm_can_tx(struct bcm_op *op)
|
||||
|
||||
can_skb_reserve(skb);
|
||||
can_skb_prv(skb)->ifindex = dev->ifindex;
|
||||
can_skb_prv(skb)->skbcnt = 0;
|
||||
|
||||
skb_put_data(skb, cf, op->cfsiz);
|
||||
|
||||
@@ -1344,7 +1343,6 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk,
|
||||
}
|
||||
|
||||
can_skb_prv(skb)->ifindex = dev->ifindex;
|
||||
can_skb_prv(skb)->skbcnt = 0;
|
||||
skb->dev = dev;
|
||||
can_skb_set_owner(skb, sk);
|
||||
err = can_send(skb, 1); /* send with loopback */
|
||||
|
||||
@@ -230,7 +230,6 @@ static int isotp_send_fc(struct sock *sk, int ae, u8 flowstatus)
|
||||
|
||||
can_skb_reserve(nskb);
|
||||
can_skb_prv(nskb)->ifindex = dev->ifindex;
|
||||
can_skb_prv(nskb)->skbcnt = 0;
|
||||
|
||||
nskb->dev = dev;
|
||||
can_skb_set_owner(nskb, sk);
|
||||
@@ -780,7 +779,6 @@ static void isotp_send_cframe(struct isotp_sock *so)
|
||||
|
||||
can_skb_reserve(skb);
|
||||
can_skb_prv(skb)->ifindex = dev->ifindex;
|
||||
can_skb_prv(skb)->skbcnt = 0;
|
||||
|
||||
cf = (struct canfd_frame *)skb->data;
|
||||
skb_put_zero(skb, so->ll.mtu);
|
||||
@@ -1009,7 +1007,6 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
|
||||
|
||||
can_skb_reserve(skb);
|
||||
can_skb_prv(skb)->ifindex = dev->ifindex;
|
||||
can_skb_prv(skb)->skbcnt = 0;
|
||||
|
||||
so->tx.len = size;
|
||||
so->tx.idx = 0;
|
||||
|
||||
@@ -897,7 +897,6 @@ static struct sk_buff *j1939_sk_alloc_skb(struct net_device *ndev,
|
||||
|
||||
can_skb_reserve(skb);
|
||||
can_skb_prv(skb)->ifindex = ndev->ifindex;
|
||||
can_skb_prv(skb)->skbcnt = 0;
|
||||
skb_reserve(skb, offsetof(struct can_frame, data));
|
||||
|
||||
ret = memcpy_from_msg(skb_put(skb, size), msg, size);
|
||||
|
||||
@@ -601,7 +601,6 @@ sk_buff *j1939_tp_tx_dat_new(struct j1939_priv *priv,
|
||||
skb->dev = priv->ndev;
|
||||
can_skb_reserve(skb);
|
||||
can_skb_prv(skb)->ifindex = priv->ndev->ifindex;
|
||||
can_skb_prv(skb)->skbcnt = 0;
|
||||
/* reserve CAN header */
|
||||
skb_reserve(skb, offsetof(struct can_frame, data));
|
||||
|
||||
@@ -1536,7 +1535,6 @@ j1939_session *j1939_session_fresh_new(struct j1939_priv *priv,
|
||||
skb->dev = priv->ndev;
|
||||
can_skb_reserve(skb);
|
||||
can_skb_prv(skb)->ifindex = priv->ndev->ifindex;
|
||||
can_skb_prv(skb)->skbcnt = 0;
|
||||
skcb = j1939_skb_to_cb(skb);
|
||||
memcpy(skcb, rel_skcb, sizeof(*skcb));
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ MODULE_ALIAS("can-proto-1");
|
||||
|
||||
struct uniqframe {
|
||||
const struct sk_buff *skb;
|
||||
int skbcnt;
|
||||
u32 hash;
|
||||
unsigned int join_rx_count;
|
||||
};
|
||||
|
||||
@@ -164,7 +164,7 @@ static void raw_rcv(struct sk_buff *oskb, void *data)
|
||||
|
||||
/* eliminate multiple filter matches for the same skb */
|
||||
if (this_cpu_ptr(ro->uniq)->skb == oskb &&
|
||||
this_cpu_ptr(ro->uniq)->skbcnt == can_skb_prv(oskb)->skbcnt) {
|
||||
this_cpu_ptr(ro->uniq)->hash == oskb->hash) {
|
||||
if (!ro->join_filters)
|
||||
return;
|
||||
|
||||
@@ -174,7 +174,7 @@ static void raw_rcv(struct sk_buff *oskb, void *data)
|
||||
return;
|
||||
} else {
|
||||
this_cpu_ptr(ro->uniq)->skb = oskb;
|
||||
this_cpu_ptr(ro->uniq)->skbcnt = can_skb_prv(oskb)->skbcnt;
|
||||
this_cpu_ptr(ro->uniq)->hash = oskb->hash;
|
||||
this_cpu_ptr(ro->uniq)->join_rx_count = 1;
|
||||
/* drop first frame to check all enabled filters? */
|
||||
if (ro->join_filters && ro->count > 1)
|
||||
@@ -958,7 +958,6 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
|
||||
|
||||
can_skb_reserve(skb);
|
||||
can_skb_prv(skb)->ifindex = dev->ifindex;
|
||||
can_skb_prv(skb)->skbcnt = 0;
|
||||
|
||||
/* fill the skb before testing for valid CAN frames */
|
||||
err = memcpy_from_msg(skb_put(skb, size), msg, size);
|
||||
|
||||
Reference in New Issue
Block a user