linux-can-fixes-for-6.16-20250617

-----BEGIN PGP SIGNATURE-----
 
 iQFHBAABCgAxFiEEn/sM2K9nqF/8FWzzDHRl3/mQkZwFAmhRji0THG1rbEBwZW5n
 dXRyb25peC5kZQAKCRAMdGXf+ZCRnIhnB/4sPyASpIMeCZh20cL8WHFKhz1F2daS
 znxvsL3sQZfol4a6pEc4/lYHEcpODitUhF4sPbMgU7qlSEysZbEsfuYZw1RLy8j9
 bsIS+LqRqSslwS2/XuLwOjXly4+bgPwc4wj2RwH9+D9TlaLkZ02NZAqDNkidPxm/
 8udZxMqorVIUhqsckfsmIqVonllz7l3InSZ3gYeXVLXAMTgsvperjVtN/YivdbPm
 H1T6b6qopUEmIqDdsKelb1D9URMoiW9exDX05OpSzxZWWeTPZyJclOraKu6Otf4W
 Jd7IVgOv03prcOcerlXZoD6tEC0Amsl1RdkPiX6csAa6m63XvxjHIJyH
 =hk/l
 -----END PGP SIGNATURE-----

Merge tag 'linux-can-fixes-for-6.16-20250617' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can

Marc Kleine-Budde says:

====================
pull-request: can 2025-06-17

The patch is by Brett Werling, and fixes the power regulator retrieval
during probe of the tcan4x5x glue code for the m_can driver.

* tag 'linux-can-fixes-for-6.16-20250617' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can:
  can: tcan4x5x: fix power regulator retrieval during probe
  openvswitch: Allocate struct ovs_pcpu_storage dynamically
====================

Link: https://patch.msgid.link/20250617155123.2141584-1-mkl@pengutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2025-06-17 15:48:38 -07:00
commit 68a4abb1ef
4 changed files with 52 additions and 25 deletions

View File

@ -411,10 +411,11 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
priv = cdev_to_priv(mcan_class);
priv->power = devm_regulator_get_optional(&spi->dev, "vsup");
if (PTR_ERR(priv->power) == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
goto out_m_can_class_free_dev;
} else {
if (IS_ERR(priv->power)) {
if (PTR_ERR(priv->power) == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
goto out_m_can_class_free_dev;
}
priv->power = NULL;
}

View File

@ -39,16 +39,14 @@
#include "flow_netlink.h"
#include "openvswitch_trace.h"
DEFINE_PER_CPU(struct ovs_pcpu_storage, ovs_pcpu_storage) = {
.bh_lock = INIT_LOCAL_LOCK(bh_lock),
};
struct ovs_pcpu_storage __percpu *ovs_pcpu_storage;
/* Make a clone of the 'key', using the pre-allocated percpu 'flow_keys'
* space. Return NULL if out of key spaces.
*/
static struct sw_flow_key *clone_key(const struct sw_flow_key *key_)
{
struct ovs_pcpu_storage *ovs_pcpu = this_cpu_ptr(&ovs_pcpu_storage);
struct ovs_pcpu_storage *ovs_pcpu = this_cpu_ptr(ovs_pcpu_storage);
struct action_flow_keys *keys = &ovs_pcpu->flow_keys;
int level = ovs_pcpu->exec_level;
struct sw_flow_key *key = NULL;
@ -94,7 +92,7 @@ static struct deferred_action *add_deferred_actions(struct sk_buff *skb,
const struct nlattr *actions,
const int actions_len)
{
struct action_fifo *fifo = this_cpu_ptr(&ovs_pcpu_storage.action_fifos);
struct action_fifo *fifo = this_cpu_ptr(&ovs_pcpu_storage->action_fifos);
struct deferred_action *da;
da = action_fifo_put(fifo);
@ -755,7 +753,7 @@ static int set_sctp(struct sk_buff *skb, struct sw_flow_key *flow_key,
static int ovs_vport_output(struct net *net, struct sock *sk,
struct sk_buff *skb)
{
struct ovs_frag_data *data = this_cpu_ptr(&ovs_pcpu_storage.frag_data);
struct ovs_frag_data *data = this_cpu_ptr(&ovs_pcpu_storage->frag_data);
struct vport *vport = data->vport;
if (skb_cow_head(skb, data->l2_len) < 0) {
@ -807,7 +805,7 @@ static void prepare_frag(struct vport *vport, struct sk_buff *skb,
unsigned int hlen = skb_network_offset(skb);
struct ovs_frag_data *data;
data = this_cpu_ptr(&ovs_pcpu_storage.frag_data);
data = this_cpu_ptr(&ovs_pcpu_storage->frag_data);
data->dst = skb->_skb_refdst;
data->vport = vport;
data->cb = *OVS_CB(skb);
@ -1566,16 +1564,15 @@ static int clone_execute(struct datapath *dp, struct sk_buff *skb,
clone = clone_flow_key ? clone_key(key) : key;
if (clone) {
int err = 0;
if (actions) { /* Sample action */
if (clone_flow_key)
__this_cpu_inc(ovs_pcpu_storage.exec_level);
__this_cpu_inc(ovs_pcpu_storage->exec_level);
err = do_execute_actions(dp, skb, clone,
actions, len);
if (clone_flow_key)
__this_cpu_dec(ovs_pcpu_storage.exec_level);
__this_cpu_dec(ovs_pcpu_storage->exec_level);
} else { /* Recirc action */
clone->recirc_id = recirc_id;
ovs_dp_process_packet(skb, clone);
@ -1611,7 +1608,7 @@ static int clone_execute(struct datapath *dp, struct sk_buff *skb,
static void process_deferred_actions(struct datapath *dp)
{
struct action_fifo *fifo = this_cpu_ptr(&ovs_pcpu_storage.action_fifos);
struct action_fifo *fifo = this_cpu_ptr(&ovs_pcpu_storage->action_fifos);
/* Do not touch the FIFO in case there is no deferred actions. */
if (action_fifo_is_empty(fifo))
@ -1642,7 +1639,7 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb,
{
int err, level;
level = __this_cpu_inc_return(ovs_pcpu_storage.exec_level);
level = __this_cpu_inc_return(ovs_pcpu_storage->exec_level);
if (unlikely(level > OVS_RECURSION_LIMIT)) {
net_crit_ratelimited("ovs: recursion limit reached on datapath %s, probable configuration error\n",
ovs_dp_name(dp));
@ -1659,6 +1656,6 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb,
process_deferred_actions(dp);
out:
__this_cpu_dec(ovs_pcpu_storage.exec_level);
__this_cpu_dec(ovs_pcpu_storage->exec_level);
return err;
}

View File

@ -244,7 +244,7 @@ void ovs_dp_detach_port(struct vport *p)
/* Must be called with rcu_read_lock. */
void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
{
struct ovs_pcpu_storage *ovs_pcpu = this_cpu_ptr(&ovs_pcpu_storage);
struct ovs_pcpu_storage *ovs_pcpu = this_cpu_ptr(ovs_pcpu_storage);
const struct vport *p = OVS_CB(skb)->input_vport;
struct datapath *dp = p->dp;
struct sw_flow *flow;
@ -299,7 +299,7 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
* avoided.
*/
if (IS_ENABLED(CONFIG_PREEMPT_RT) && ovs_pcpu->owner != current) {
local_lock_nested_bh(&ovs_pcpu_storage.bh_lock);
local_lock_nested_bh(&ovs_pcpu_storage->bh_lock);
ovs_pcpu->owner = current;
ovs_pcpu_locked = true;
}
@ -310,7 +310,7 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
ovs_dp_name(dp), error);
if (ovs_pcpu_locked) {
ovs_pcpu->owner = NULL;
local_unlock_nested_bh(&ovs_pcpu_storage.bh_lock);
local_unlock_nested_bh(&ovs_pcpu_storage->bh_lock);
}
stats_counter = &stats->n_hit;
@ -689,13 +689,13 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
sf_acts = rcu_dereference(flow->sf_acts);
local_bh_disable();
local_lock_nested_bh(&ovs_pcpu_storage.bh_lock);
local_lock_nested_bh(&ovs_pcpu_storage->bh_lock);
if (IS_ENABLED(CONFIG_PREEMPT_RT))
this_cpu_write(ovs_pcpu_storage.owner, current);
this_cpu_write(ovs_pcpu_storage->owner, current);
err = ovs_execute_actions(dp, packet, sf_acts, &flow->key);
if (IS_ENABLED(CONFIG_PREEMPT_RT))
this_cpu_write(ovs_pcpu_storage.owner, NULL);
local_unlock_nested_bh(&ovs_pcpu_storage.bh_lock);
this_cpu_write(ovs_pcpu_storage->owner, NULL);
local_unlock_nested_bh(&ovs_pcpu_storage->bh_lock);
local_bh_enable();
rcu_read_unlock();
@ -2744,6 +2744,28 @@ static struct drop_reason_list drop_reason_list_ovs = {
.n_reasons = ARRAY_SIZE(ovs_drop_reasons),
};
static int __init ovs_alloc_percpu_storage(void)
{
unsigned int cpu;
ovs_pcpu_storage = alloc_percpu(*ovs_pcpu_storage);
if (!ovs_pcpu_storage)
return -ENOMEM;
for_each_possible_cpu(cpu) {
struct ovs_pcpu_storage *ovs_pcpu;
ovs_pcpu = per_cpu_ptr(ovs_pcpu_storage, cpu);
local_lock_init(&ovs_pcpu->bh_lock);
}
return 0;
}
static void ovs_free_percpu_storage(void)
{
free_percpu(ovs_pcpu_storage);
}
static int __init dp_init(void)
{
int err;
@ -2753,6 +2775,10 @@ static int __init dp_init(void)
pr_info("Open vSwitch switching datapath\n");
err = ovs_alloc_percpu_storage();
if (err)
goto error;
err = ovs_internal_dev_rtnl_link_register();
if (err)
goto error;
@ -2799,6 +2825,7 @@ static int __init dp_init(void)
error_unreg_rtnl_link:
ovs_internal_dev_rtnl_link_unregister();
error:
ovs_free_percpu_storage();
return err;
}
@ -2813,6 +2840,7 @@ static void dp_cleanup(void)
ovs_vport_exit();
ovs_flow_exit();
ovs_internal_dev_rtnl_link_unregister();
ovs_free_percpu_storage();
}
module_init(dp_init);

View File

@ -220,7 +220,8 @@ struct ovs_pcpu_storage {
struct task_struct *owner;
local_lock_t bh_lock;
};
DECLARE_PER_CPU(struct ovs_pcpu_storage, ovs_pcpu_storage);
extern struct ovs_pcpu_storage __percpu *ovs_pcpu_storage;
/**
* enum ovs_pkt_hash_types - hash info to include with a packet