net: define an enum for the napi threaded state

Instead of using '0' and '1' for napi threaded state use an enum with
'disabled' and 'enabled' states.

Tested:
 ./tools/testing/selftests/net/nl_netdev.py
 TAP version 13
 1..7
 ok 1 nl_netdev.empty_check
 ok 2 nl_netdev.lo_check
 ok 3 nl_netdev.page_pool_check
 ok 4 nl_netdev.napi_list_check
 ok 5 nl_netdev.dev_set_threaded
 ok 6 nl_netdev.napi_set_threaded
 ok 7 nl_netdev.nsim_rxq_reset_down
 # Totals: pass:7 fail:0 xfail:0 xpass:0 skip:0 error:0

Signed-off-by: Samiullah Khawaja <skhawaja@google.com>
Link: https://patch.msgid.link/20250723013031.2911384-4-skhawaja@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Samiullah Khawaja
2025-07-23 01:30:31 +00:00
committed by Jakub Kicinski
parent 78afdadafe
commit 8e7583a4f6
11 changed files with 62 additions and 41 deletions

View File

@@ -85,6 +85,10 @@ definitions:
name: qstats-scope
type: flags
entries: [queue]
-
name: napi-threaded
type: enum
entries: [disabled, enabled]
attribute-sets:
-
@@ -286,11 +290,10 @@ attribute-sets:
-
name: threaded
doc: Whether the NAPI is configured to operate in threaded polling
mode. If this is set to 1 then the NAPI context operates in
threaded polling mode.
type: uint
checks:
max: 1
mode. If this is set to enabled then the NAPI context operates
in threaded polling mode.
type: u32
enum: napi-threaded
-
name: xsk-info
attributes: []

View File

@@ -68,6 +68,7 @@ unsigned_char addr_assign_type
unsigned_char addr_len
unsigned_char upper_level
unsigned_char lower_level
u8 threaded napi_poll(napi_enable,netif_set_threaded)
unsigned_short neigh_priv_len
unsigned_short padded
unsigned_short dev_id
@@ -165,7 +166,6 @@ struct sfp_bus* sfp_bus
struct lock_class_key* qdisc_tx_busylock
bool proto_down
unsigned:1 wol_enabled
unsigned:1 threaded napi_poll(napi_enable,netif_set_threaded)
unsigned_long:1 see_all_hwtstamp_requests
unsigned_long:1 change_proto_down
unsigned_long:1 netns_immutable

View File

@@ -369,7 +369,7 @@ struct napi_config {
u64 irq_suspend_timeout;
u32 defer_hard_irqs;
cpumask_t affinity_mask;
bool threaded;
u8 threaded;
unsigned int napi_id;
};
@@ -590,7 +590,8 @@ static inline bool napi_complete(struct napi_struct *n)
}
void netif_threaded_enable(struct net_device *dev);
int dev_set_threaded(struct net_device *dev, bool threaded);
int dev_set_threaded(struct net_device *dev,
enum netdev_napi_threaded threaded);
void napi_disable(struct napi_struct *n);
void napi_disable_locked(struct napi_struct *n);
@@ -1872,6 +1873,7 @@ enum netdev_reg_state {
* @addr_len: Hardware address length
* @upper_level: Maximum depth level of upper devices.
* @lower_level: Maximum depth level of lower devices.
* @threaded: napi threaded state.
* @neigh_priv_len: Used in neigh_alloc()
* @dev_id: Used to differentiate devices that share
* the same link layer address
@@ -2011,8 +2013,6 @@ enum netdev_reg_state {
* switch driver and used to set the phys state of the
* switch port.
*
* @threaded: napi threaded mode is enabled
*
* @irq_affinity_auto: driver wants the core to store and re-assign the IRQ
* affinity. Set by netif_enable_irq_affinity(), then
* the driver must create a persistent napi by
@@ -2248,6 +2248,7 @@ struct net_device {
unsigned char addr_len;
unsigned char upper_level;
unsigned char lower_level;
u8 threaded;
unsigned short neigh_priv_len;
unsigned short dev_id;
@@ -2429,7 +2430,6 @@ struct net_device {
struct sfp_bus *sfp_bus;
struct lock_class_key *qdisc_tx_busylock;
bool proto_down;
bool threaded;
bool irq_affinity_auto;
bool rx_cpu_rmap_auto;

View File

@@ -77,6 +77,11 @@ enum netdev_qstats_scope {
NETDEV_QSTATS_SCOPE_QUEUE = 1,
};
enum netdev_napi_threaded {
NETDEV_NAPI_THREADED_DISABLED,
NETDEV_NAPI_THREADED_ENABLED,
};
enum {
NETDEV_A_DEV_IFINDEX = 1,
NETDEV_A_DEV_PAD,

View File

@@ -6963,7 +6963,8 @@ static void napi_stop_kthread(struct napi_struct *napi)
napi->thread = NULL;
}
int napi_set_threaded(struct napi_struct *napi, bool threaded)
int napi_set_threaded(struct napi_struct *napi,
enum netdev_napi_threaded threaded)
{
if (threaded) {
if (!napi->thread) {
@@ -6988,7 +6989,8 @@ int napi_set_threaded(struct napi_struct *napi, bool threaded)
return 0;
}
int netif_set_threaded(struct net_device *dev, bool threaded)
int netif_set_threaded(struct net_device *dev,
enum netdev_napi_threaded threaded)
{
struct napi_struct *napi;
int err = 0;
@@ -7000,7 +7002,7 @@ int netif_set_threaded(struct net_device *dev, bool threaded)
if (!napi->thread) {
err = napi_kthread_create(napi);
if (err) {
threaded = false;
threaded = NETDEV_NAPI_THREADED_DISABLED;
break;
}
}
@@ -7043,7 +7045,7 @@ int netif_set_threaded(struct net_device *dev, bool threaded)
*/
void netif_threaded_enable(struct net_device *dev)
{
WARN_ON_ONCE(netif_set_threaded(dev, true));
WARN_ON_ONCE(netif_set_threaded(dev, NETDEV_NAPI_THREADED_ENABLED));
}
EXPORT_SYMBOL(netif_threaded_enable);
@@ -7360,7 +7362,7 @@ void netif_napi_add_weight_locked(struct net_device *dev,
* threaded mode will not be enabled in napi_enable().
*/
if (dev->threaded && napi_kthread_create(napi))
dev->threaded = false;
dev->threaded = NETDEV_NAPI_THREADED_DISABLED;
netif_napi_set_irq_locked(napi, -1);
}
EXPORT_SYMBOL(netif_napi_add_weight_locked);

View File

@@ -315,14 +315,19 @@ static inline void napi_set_irq_suspend_timeout(struct napi_struct *n,
WRITE_ONCE(n->irq_suspend_timeout, timeout);
}
static inline bool napi_get_threaded(struct napi_struct *n)
static inline enum netdev_napi_threaded napi_get_threaded(struct napi_struct *n)
{
return test_bit(NAPI_STATE_THREADED, &n->state);
if (test_bit(NAPI_STATE_THREADED, &n->state))
return NETDEV_NAPI_THREADED_ENABLED;
return NETDEV_NAPI_THREADED_DISABLED;
}
int napi_set_threaded(struct napi_struct *n, bool threaded);
int napi_set_threaded(struct napi_struct *n,
enum netdev_napi_threaded threaded);
int netif_set_threaded(struct net_device *dev, bool threaded);
int netif_set_threaded(struct net_device *dev,
enum netdev_napi_threaded threaded);
int rps_cpumask_housekeeping(struct cpumask *mask);

View File

@@ -368,7 +368,8 @@ void netdev_state_change(struct net_device *dev)
}
EXPORT_SYMBOL(netdev_state_change);
int dev_set_threaded(struct net_device *dev, bool threaded)
int dev_set_threaded(struct net_device *dev,
enum netdev_napi_threaded threaded)
{
int ret;

View File

@@ -97,7 +97,7 @@ static const struct nla_policy netdev_napi_set_nl_policy[NETDEV_A_NAPI_THREADED
[NETDEV_A_NAPI_DEFER_HARD_IRQS] = NLA_POLICY_FULL_RANGE(NLA_U32, &netdev_a_napi_defer_hard_irqs_range),
[NETDEV_A_NAPI_GRO_FLUSH_TIMEOUT] = { .type = NLA_UINT, },
[NETDEV_A_NAPI_IRQ_SUSPEND_TIMEOUT] = { .type = NLA_UINT, },
[NETDEV_A_NAPI_THREADED] = NLA_POLICY_MAX(NLA_UINT, 1),
[NETDEV_A_NAPI_THREADED] = NLA_POLICY_MAX(NLA_U32, 1),
};
/* NETDEV_CMD_BIND_TX - do */

View File

@@ -333,7 +333,7 @@ netdev_nl_napi_set_config(struct napi_struct *napi, struct genl_info *info)
int ret;
threaded = nla_get_uint(info->attrs[NETDEV_A_NAPI_THREADED]);
ret = napi_set_threaded(napi, !!threaded);
ret = napi_set_threaded(napi, threaded);
if (ret)
return ret;
}

View File

@@ -77,6 +77,11 @@ enum netdev_qstats_scope {
NETDEV_QSTATS_SCOPE_QUEUE = 1,
};
enum netdev_napi_threaded {
NETDEV_NAPI_THREADED_DISABLED,
NETDEV_NAPI_THREADED_ENABLED,
};
enum {
NETDEV_A_DEV_IFINDEX = 1,
NETDEV_A_DEV_PAD,

View File

@@ -52,14 +52,14 @@ def napi_set_threaded(nf) -> None:
napi1_id = napis[1]['id']
# set napi threaded and verify
nf.napi_set({'id': napi0_id, 'threaded': 1})
nf.napi_set({'id': napi0_id, 'threaded': "enabled"})
napi0 = nf.napi_get({'id': napi0_id})
ksft_eq(napi0['threaded'], 1)
ksft_eq(napi0['threaded'], "enabled")
ksft_ne(napi0.get('pid'), None)
# check it is not set for napi1
napi1 = nf.napi_get({'id': napi1_id})
ksft_eq(napi1['threaded'], 0)
ksft_eq(napi1['threaded'], "disabled")
ksft_eq(napi1.get('pid'), None)
ip(f"link set dev {nsim.ifname} down")
@@ -67,18 +67,18 @@ def napi_set_threaded(nf) -> None:
# verify if napi threaded is still set
napi0 = nf.napi_get({'id': napi0_id})
ksft_eq(napi0['threaded'], 1)
ksft_eq(napi0['threaded'], "enabled")
ksft_ne(napi0.get('pid'), None)
# check it is still not set for napi1
napi1 = nf.napi_get({'id': napi1_id})
ksft_eq(napi1['threaded'], 0)
ksft_eq(napi1['threaded'], "disabled")
ksft_eq(napi1.get('pid'), None)
# unset napi threaded and verify
nf.napi_set({'id': napi0_id, 'threaded': 0})
nf.napi_set({'id': napi0_id, 'threaded': "disabled"})
napi0 = nf.napi_get({'id': napi0_id})
ksft_eq(napi0['threaded'], 0)
ksft_eq(napi0['threaded'], "disabled")
ksft_eq(napi0.get('pid'), None)
# set threaded at device level
@@ -86,10 +86,10 @@ def napi_set_threaded(nf) -> None:
# check napi threaded is set for both napis
napi0 = nf.napi_get({'id': napi0_id})
ksft_eq(napi0['threaded'], 1)
ksft_eq(napi0['threaded'], "enabled")
ksft_ne(napi0.get('pid'), None)
napi1 = nf.napi_get({'id': napi1_id})
ksft_eq(napi1['threaded'], 1)
ksft_eq(napi1['threaded'], "enabled")
ksft_ne(napi1.get('pid'), None)
# unset threaded at device level
@@ -97,16 +97,16 @@ def napi_set_threaded(nf) -> None:
# check napi threaded is unset for both napis
napi0 = nf.napi_get({'id': napi0_id})
ksft_eq(napi0['threaded'], 0)
ksft_eq(napi0['threaded'], "disabled")
ksft_eq(napi0.get('pid'), None)
napi1 = nf.napi_get({'id': napi1_id})
ksft_eq(napi1['threaded'], 0)
ksft_eq(napi1['threaded'], "disabled")
ksft_eq(napi1.get('pid'), None)
# set napi threaded for napi0
nf.napi_set({'id': napi0_id, 'threaded': 1})
napi0 = nf.napi_get({'id': napi0_id})
ksft_eq(napi0['threaded'], 1)
ksft_eq(napi0['threaded'], "enabled")
ksft_ne(napi0.get('pid'), None)
# unset threaded at device level
@@ -114,10 +114,10 @@ def napi_set_threaded(nf) -> None:
# check napi threaded is unset for both napis
napi0 = nf.napi_get({'id': napi0_id})
ksft_eq(napi0['threaded'], 0)
ksft_eq(napi0['threaded'], "disabled")
ksft_eq(napi0.get('pid'), None)
napi1 = nf.napi_get({'id': napi1_id})
ksft_eq(napi1['threaded'], 0)
ksft_eq(napi1['threaded'], "disabled")
ksft_eq(napi1.get('pid'), None)
def dev_set_threaded(nf) -> None:
@@ -141,10 +141,10 @@ def dev_set_threaded(nf) -> None:
# check napi threaded is set for both napis
napi0 = nf.napi_get({'id': napi0_id})
ksft_eq(napi0['threaded'], 1)
ksft_eq(napi0['threaded'], "enabled")
ksft_ne(napi0.get('pid'), None)
napi1 = nf.napi_get({'id': napi1_id})
ksft_eq(napi1['threaded'], 1)
ksft_eq(napi1['threaded'], "enabled")
ksft_ne(napi1.get('pid'), None)
# unset threaded
@@ -152,10 +152,10 @@ def dev_set_threaded(nf) -> None:
# check napi threaded is unset for both napis
napi0 = nf.napi_get({'id': napi0_id})
ksft_eq(napi0['threaded'], 0)
ksft_eq(napi0['threaded'], "disabled")
ksft_eq(napi0.get('pid'), None)
napi1 = nf.napi_get({'id': napi1_id})
ksft_eq(napi1['threaded'], 0)
ksft_eq(napi1['threaded'], "disabled")
ksft_eq(napi1.get('pid'), None)
def nsim_rxq_reset_down(nf) -> None: