Commit 27ce71e1 authored by Marco Crivellari's avatar Marco Crivellari Committed by Jakub Kicinski
Browse files

net: WQ_PERCPU added to alloc_workqueue users



Currently if a user enqueue a work item using schedule_delayed_work() the
used wq is "system_wq" (per-cpu wq) while queue_delayed_work() use
WORK_CPU_UNBOUND (used when a cpu is not specified). The same applies to
schedule_work() that is using system_wq and queue_work(), that makes use
again of WORK_CPU_UNBOUND.
This lack of consistentcy cannot be addressed without refactoring the API.

alloc_workqueue() treats all queues as per-CPU by default, while unbound
workqueues must opt-in via WQ_UNBOUND.

This default is suboptimal: most workloads benefit from unbound queues,
allowing the scheduler to place worker threads where they’re needed and
reducing noise when CPUs are isolated.

This change adds a new WQ_PERCPU flag at the network subsystem, to explicitly
request the use of the per-CPU behavior. Both flags coexist for one release
cycle to allow callers to transition their calls.

Once migration is complete, WQ_UNBOUND can be removed and unbound will
become the implicit default.

With the introduction of the WQ_PERCPU flag (equivalent to !WQ_UNBOUND),
any alloc_workqueue() caller that doesn’t explicitly specify WQ_UNBOUND
must now use WQ_PERCPU.

All existing users have been updated accordingly.

Suggested-by: default avatarTejun Heo <tj@kernel.org>
Signed-off-by: default avatarMarco Crivellari <marco.crivellari@suse.com>
Link: https://patch.msgid.link/20250918142427.309519-4-marco.crivellari@suse.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 5fd8bb98
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -770,7 +770,8 @@ static int hi3110_open(struct net_device *net)
		goto out_close;
	}

	priv->wq = alloc_workqueue("hi3110_wq", WQ_FREEZABLE | WQ_MEM_RECLAIM,
	priv->wq = alloc_workqueue("hi3110_wq",
				   WQ_FREEZABLE | WQ_MEM_RECLAIM | WQ_PERCPU,
				   0);
	if (!priv->wq) {
		ret = -ENOMEM;
+2 −1
Original line number Diff line number Diff line
@@ -1378,7 +1378,8 @@ static int mcp251x_can_probe(struct spi_device *spi)
	if (ret)
		goto out_clk;

	priv->wq = alloc_workqueue("mcp251x_wq", WQ_FREEZABLE | WQ_MEM_RECLAIM,
	priv->wq = alloc_workqueue("mcp251x_wq",
				   WQ_FREEZABLE | WQ_MEM_RECLAIM | WQ_PERCPU,
				   0);
	if (!priv->wq) {
		ret = -ENOMEM;
+1 −1
Original line number Diff line number Diff line
@@ -472,7 +472,7 @@ int setup_rx_oom_poll_fn(struct net_device *netdev)
		q_no = lio->linfo.rxpciq[q].s.q_no;
		wq = &lio->rxq_status_wq[q_no];
		wq->wq = alloc_workqueue("rxq-oom-status",
					 WQ_MEM_RECLAIM, 0);
					 WQ_MEM_RECLAIM | WQ_PERCPU, 0);
		if (!wq->wq) {
			dev_err(&oct->pci_dev->dev, "unable to create cavium rxq oom status wq\n");
			return -ENOMEM;
+5 −3
Original line number Diff line number Diff line
@@ -526,7 +526,8 @@ static inline int setup_link_status_change_wq(struct net_device *netdev)
	struct octeon_device *oct = lio->oct_dev;

	lio->link_status_wq.wq = alloc_workqueue("link-status",
						 WQ_MEM_RECLAIM, 0);
						 WQ_MEM_RECLAIM | WQ_PERCPU,
						 0);
	if (!lio->link_status_wq.wq) {
		dev_err(&oct->pci_dev->dev, "unable to create cavium link status wq\n");
		return -1;
@@ -659,7 +660,8 @@ static inline int setup_sync_octeon_time_wq(struct net_device *netdev)
	struct octeon_device *oct = lio->oct_dev;

	lio->sync_octeon_time_wq.wq =
		alloc_workqueue("update-octeon-time", WQ_MEM_RECLAIM, 0);
		alloc_workqueue("update-octeon-time",
				WQ_MEM_RECLAIM | WQ_PERCPU, 0);
	if (!lio->sync_octeon_time_wq.wq) {
		dev_err(&oct->pci_dev->dev, "Unable to create wq to update octeon time\n");
		return -1;
@@ -1734,7 +1736,7 @@ static inline int setup_tx_poll_fn(struct net_device *netdev)
	struct octeon_device *oct = lio->oct_dev;

	lio->txq_status_wq.wq = alloc_workqueue("txq-status",
						WQ_MEM_RECLAIM, 0);
						WQ_MEM_RECLAIM | WQ_PERCPU, 0);
	if (!lio->txq_status_wq.wq) {
		dev_err(&oct->pci_dev->dev, "unable to create cavium txq status wq\n");
		return -1;
+2 −1
Original line number Diff line number Diff line
@@ -304,7 +304,8 @@ static int setup_link_status_change_wq(struct net_device *netdev)
	struct octeon_device *oct = lio->oct_dev;

	lio->link_status_wq.wq = alloc_workqueue("link-status",
						 WQ_MEM_RECLAIM, 0);
						 WQ_MEM_RECLAIM | WQ_PERCPU,
						 0);
	if (!lio->link_status_wq.wq) {
		dev_err(&oct->pci_dev->dev, "unable to create cavium link status wq\n");
		return -1;
Loading