Debian: porting kernel commits from centos

To keep kernel debian stx aligned with centos stx, porting below commits
from centos stx to debian stx:
(1)patches related
   ef3c9a4 kernel: Add auxiliary bus support
   19ca0df kernel: Backport IRQ affinity patches
   a10b746 workqueue affinity: Remove unused variable
   8fde1a8 kthread_cpus: Avoid large stack allocation
   bb6ec66 scsi: Make the disk detection order more consistent
   bf940a8 rcu: Avoid RCU-related unexpected reboot
   cfe452a workqueue: Affine rescuer threads and unbound wqs
(2)config related
   6fe8d60 kernel: Disable NVMe multi-path kconfig option
   c9cdb90 Fixup recent kconfig cleanup
   8551799 Resolve v5.10 kernel configuration file differences
(3)kernel-modules related
   7ded004 kernel-modules: IRQ affinity hint fix-ups

Please pay attention to:
[ef3c9a4 kernel: Add auxiliary bus support]
which is not only related with kernel patches but also related with
kernel-modules.
It removes the auxiliary.ko from the oot ice package because auxiliary
bus device driver is built into kernel. But the detecting of builtin
auxiliary driver in intel-iavf/intel-ice oot driver will fail because
debian has 2 linux header packages. So extra patches are added for
intel-iavf and intel-ice to pass linux common header to check_aux_bus
to make builtin auxiliary driver detected. At the same time the patch
[check_aux_bus: Look for kernel headers in the right location]
for the oot drivers is removed because it isn't needed any more if
the right header path is passed.

Test Plan:
 - PASS: Build kernel-std/kernel-rt.
 - PASS: Build the 7 oot kernel modules for kernel-std/kernel-rt.
 - PASS: Build the iso for kernel-std and modules and boot up on qemu.
 - PASS: Build the test iso for kernel-rt and modules and boot up
         on qemu.

Story: 2009221
Task: 44989
Signed-off-by: Li Zhou <li.zhou@windriver.com>
Change-Id: Ic7cddc068eab1516800e90bfe431d042274f86d3
This commit is contained in:
Li Zhou 2022-04-08 02:31:41 +00:00
parent c3ca31a024
commit 998d337c2b
56 changed files with 7333 additions and 103 deletions

View File

@ -0,0 +1,61 @@
From 2ae84a0ff5b9d12aac1394965ff21d636fc3162b Mon Sep 17 00:00:00 2001
From: "M. Vefa Bicakci" <vefa.bicakci@windriver.com>
Date: Fri, 14 Jan 2022 17:25:25 -0500
Subject: [PATCH] i40e_main: Use irq_update_affinity_hint
This commit makes i40e_main use irq_update_affinity_hint instead of
irq_set_affinity_hint to set the CPU affinity hints. This is done
because the latter function sets the IRQ CPU affinities, whereas the
former does not, and this allows the use of the default IRQ affinity CPU
mask provided via the irqaffinity= kernel command line option.
This commit essentially replicates the i40e patch in the following
patch series:
https://lore.kernel.org/netdev/20210903152430.244937-1-nitesh@redhat.com/t/#u
The i40e patch has been mainlined as of this writing:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34c54d1739c2cdf2e4437b74e6da269147f4987
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
src/i40e_main.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/i40e_main.c b/src/i40e_main.c
index 874644bc0c1a..0bb06d3172b7 100644
--- a/src/i40e_main.c
+++ b/src/i40e_main.c
@@ -4761,10 +4761,10 @@ int i40e_vsi_request_irq_msix(struct i40e_vsi *vsi, char *basename)
*
* get_cpu_mask returns a static constant mask with
* a permanent lifetime so it's ok to pass to
- * irq_set_affinity_hint without making a copy.
+ * irq_update_affinity_hint without making a copy.
*/
cpu = cpumask_local_spread(q_vector->v_idx, -1);
- irq_set_affinity_hint(irq_num, get_cpu_mask(cpu));
+ irq_update_affinity_hint(irq_num, get_cpu_mask(cpu));
#endif /* HAVE_IRQ_AFFINITY_HINT */
}
@@ -4779,7 +4779,7 @@ free_queue_irqs:
irq_set_affinity_notifier(irq_num, NULL);
#endif
#ifdef HAVE_IRQ_AFFINITY_HINT
- irq_set_affinity_hint(irq_num, NULL);
+ irq_update_affinity_hint(irq_num, NULL);
#endif
free_irq(irq_num, &vsi->q_vectors[vector]);
}
@@ -5594,7 +5594,7 @@ static void i40e_vsi_free_irq(struct i40e_vsi *vsi)
#endif
#ifdef HAVE_IRQ_AFFINITY_HINT
/* remove our suggested affinity mask for this IRQ */
- irq_set_affinity_hint(irq_num, NULL);
+ irq_update_affinity_hint(irq_num, NULL);
#endif
synchronize_irq(irq_num);
free_irq(irq_num, vsi->q_vectors[i]);
--
2.29.2

View File

@ -1,2 +1,3 @@
i40e-Enable-getting-link-status-from-VF.patch
i40e-add-more-debug-info-for-VFs-still-in-reset.patch
i40e_main-Use-irq_update_affinity_hint.patch

View File

@ -1,29 +0,0 @@
From ed1fd30875a61bc36fd0d652cd04d532551ad4a1 Mon Sep 17 00:00:00 2001
Message-Id: <ed1fd30875a61bc36fd0d652cd04d532551ad4a1.1645648932.git.Jim.Somerville@windriver.com>
From: Jim Somerville <Jim.Somerville@windriver.com>
Date: Tue, 22 Feb 2022 17:41:51 -0500
Subject: [PATCH] check_aux_bus: Look for kernel headers in the right location
Debian puts them under include/config
Signed-off-by: Jim Somerville <Jim.Somerville@windriver.com>
---
scripts/check_aux_bus | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/check_aux_bus b/scripts/check_aux_bus
index f3e1b54..14494e4 100755
--- a/scripts/check_aux_bus
+++ b/scripts/check_aux_bus
@@ -62,7 +62,7 @@ find_aux_bus_inc()
msg "auxiliary_bus.h location: ${aux_bus_inc}"
}
-LINUX_INCLUDE_DIR="include/linux"
+LINUX_INCLUDE_DIR="include/config"
set_build_kernel()
{
--
2.29.2

View File

@ -0,0 +1,39 @@
From f5c58571e3f4278082e87bdbb2be565d61c0a21c Mon Sep 17 00:00:00 2001
From: Li Zhou <li.zhou@windriver.com>
Date: Thu, 7 Apr 2022 11:42:47 +0800
Subject: [PATCH] intel-iavf: pass linux common header to check_aux_bus
For debian, there are two header pkgs, e.g. linux-headers-5.10.0-6-amd64
and linux-headers-5.10.0-6-common. linux-headers-5.10.0-6-amd64 is
enough before check_aux_bus is added. But check_aux_bus need files
in linux-headers-5.10.0-6-common. So pass linux-headers-5.10.0-6-common
path as the KSRC for check_aux_bus when KSRC_COMMON is exported in
debian rules.
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
src/common.mk | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/common.mk b/src/common.mk
index e164d13..b2b4fe2 100644
--- a/src/common.mk
+++ b/src/common.mk
@@ -373,8 +373,13 @@ export INSTALL_MOD_DIR ?= updates/drivers/net/ethernet/intel/${DRIVER}
# If the check_aux_bus script exists, then this driver depends on the
# auxiliary module. Run the script to determine if we need to include
# auxiliary files with this build.
+ifeq (${KSRC_COMMON},)
+KSRC_AUX := ${KSRC}
+else
+KSRC_AUX := ${KSRC_COMMON}
+endif
ifneq ($(call test_file,../scripts/check_aux_bus),)
-NEED_AUX_BUS := $(shell ../scripts/check_aux_bus --ksrc="${KSRC}" --build-kernel="${BUILD_KERNEL}" >/dev/null 2>&1; echo $$?)
+NEED_AUX_BUS := $(shell ../scripts/check_aux_bus --ksrc="${KSRC_AUX}" --build-kernel="${BUILD_KERNEL}" >/dev/null 2>&1; echo $$?)
endif # check_aux_bus exists
# The out-of-tree auxiliary module we ship should be moved into this
--
2.17.1

View File

@ -0,0 +1,61 @@
From 1b24525e2971c01eafe7ac0f950dfb3a012035cf Mon Sep 17 00:00:00 2001
From: "M. Vefa Bicakci" <vefa.bicakci@windriver.com>
Date: Fri, 14 Jan 2022 17:39:52 -0500
Subject: [PATCH] iavf_main: Use irq_update_affinity_hint
This commit makes iavf_main use irq_update_affinity_hint instead of
irq_set_affinity_hint to set the CPU affinity hints. This is done
because the latter function sets the IRQ CPU affinities, whereas the
former does not, and this allows the use of the default IRQ affinity CPU
mask provided via the irqaffinity= kernel command line option.
This commit essentially replicates the iavf patch in the following
patch series:
https://lore.kernel.org/netdev/20210903152430.244937-1-nitesh@redhat.com/t/#u
The iavf patch has been mainlined as of this writing:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0f9744f4ed539f2e847d7ed41993b243e3ba5cff
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
src/iavf_main.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/iavf_main.c b/src/iavf_main.c
index 8af856576e34..65bf4e939ea3 100644
--- a/src/iavf_main.c
+++ b/src/iavf_main.c
@@ -435,10 +435,10 @@ iavf_request_traffic_irqs(struct iavf_adapter *adapter, char *basename)
#ifdef HAVE_IRQ_AFFINITY_HINT
/* Spread the IRQ affinity hints across online CPUs. Note that
* get_cpu_mask returns a mask with a permanent lifetime so
- * it's safe to use as a hint for irq_set_affinity_hint.
+ * it's safe to use as a hint for irq_update_affinity_hint.
*/
cpu = cpumask_local_spread(q_vector->v_idx, -1);
- irq_set_affinity_hint(irq_num, get_cpu_mask(cpu));
+ irq_update_affinity_hint(irq_num, get_cpu_mask(cpu));
#endif /* HAVE_IRQ_AFFINITY_HINT */
}
@@ -452,7 +452,7 @@ free_queue_irqs:
irq_set_affinity_notifier(irq_num, NULL);
#endif
#ifdef HAVE_IRQ_AFFINITY_HINT
- irq_set_affinity_hint(irq_num, NULL);
+ irq_update_affinity_hint(irq_num, NULL);
#endif
free_irq(irq_num, &adapter->q_vectors[vector]);
}
@@ -508,7 +508,7 @@ static void iavf_free_traffic_irqs(struct iavf_adapter *adapter)
irq_set_affinity_notifier(irq_num, NULL);
#endif
#ifdef HAVE_IRQ_AFFINITY_HINT
- irq_set_affinity_hint(irq_num, NULL);
+ irq_update_affinity_hint(irq_num, NULL);
#endif
free_irq(irq_num, &adapter->q_vectors[vector]);
}
--
2.29.2

View File

@ -1 +1,2 @@
0001-check_aux_bus-Look-for-kernel-headers-in-the-right-l.patch
iavf_main-Use-irq_update_affinity_hint.patch
0001-intel-iavf-pass-linux-common-header-to-check_aux_bus.patch

View File

@ -27,7 +27,9 @@
WITH_MOD_SIGN ?= 1
kheaders_name=$(shell ls /usr/src | grep linux@KERNEL_TYPE@-headers | grep amd64)
kheaders_common=$(shell ls /usr/src | grep linux@KERNEL_TYPE@-headers | grep common)
export KSRC=/usr/src/$(kheaders_name)
export KSRC_COMMON=/usr/src/$(kheaders_common)
kversion=$(shell echo $(kheaders_name) | sed 's/linux@KERNEL_TYPE@-headers-//g')
kmod_name=iavf
version=$(shell dpkg-parsechangelog | sed -n 's/^Version: *\([^-]\+\)-.\+/\1/p')

View File

@ -1,29 +0,0 @@
From ed1fd30875a61bc36fd0d652cd04d532551ad4a1 Mon Sep 17 00:00:00 2001
Message-Id: <ed1fd30875a61bc36fd0d652cd04d532551ad4a1.1645648932.git.Jim.Somerville@windriver.com>
From: Jim Somerville <Jim.Somerville@windriver.com>
Date: Tue, 22 Feb 2022 17:41:51 -0500
Subject: [PATCH] check_aux_bus: Look for kernel headers in the right location
Debian puts them under include/config
Signed-off-by: Jim Somerville <Jim.Somerville@windriver.com>
---
scripts/check_aux_bus | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/check_aux_bus b/scripts/check_aux_bus
index f3e1b54..14494e4 100755
--- a/scripts/check_aux_bus
+++ b/scripts/check_aux_bus
@@ -62,7 +62,7 @@ find_aux_bus_inc()
msg "auxiliary_bus.h location: ${aux_bus_inc}"
}
-LINUX_INCLUDE_DIR="include/linux"
+LINUX_INCLUDE_DIR="include/config"
set_build_kernel()
{
--
2.29.2

View File

@ -0,0 +1,39 @@
From 3e23e587e91eaa7425dd0f24e9edc783182a485a Mon Sep 17 00:00:00 2001
From: Li Zhou <li.zhou@windriver.com>
Date: Thu, 7 Apr 2022 11:42:47 +0800
Subject: [PATCH] intel-ice: pass linux common header to check_aux_bus
For debian, there are two header pkgs, e.g. linux-headers-5.10.0-6-amd64
and linux-headers-5.10.0-6-common. linux-headers-5.10.0-6-amd64 is
enough before check_aux_bus is added. But check_aux_bus need files
in linux-headers-5.10.0-6-common. So pass linux-headers-5.10.0-6-common
path as the KSRC for check_aux_bus when KSRC_COMMON is exported in
debian rules.
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
src/common.mk | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/common.mk b/src/common.mk
index 80f30ab..8cf8bab 100644
--- a/src/common.mk
+++ b/src/common.mk
@@ -372,8 +372,13 @@ export INSTALL_MOD_DIR ?= updates/drivers/net/ethernet/intel/${DRIVER}
# If the check_aux_bus script exists, then this driver depends on the
# auxiliary module. Run the script to determine if we need to include
# auxiliary files with this build.
+ifeq (${KSRC_COMMON},)
+KSRC_AUX := ${KSRC}
+else
+KSRC_AUX := ${KSRC_COMMON}
+endif
ifneq ($(call test_file,../scripts/check_aux_bus),)
-NEED_AUX_BUS := $(shell ../scripts/check_aux_bus --ksrc="${KSRC}" --build-kernel="${BUILD_KERNEL}" >/dev/null 2>&1; echo $$?)
+NEED_AUX_BUS := $(shell ../scripts/check_aux_bus --ksrc="${KSRC_AUX}" --build-kernel="${BUILD_KERNEL}" >/dev/null 2>&1; echo $$?)
endif # check_aux_bus exists
# The out-of-tree auxiliary module we ship should be moved into this
--
2.17.1

View File

@ -0,0 +1,70 @@
From 2c0df5cef9bfdeb934102d18df38e4024381298f Mon Sep 17 00:00:00 2001
From: "M. Vefa Bicakci" <vefa.bicakci@windriver.com>
Date: Fri, 14 Jan 2022 17:50:39 -0500
Subject: [PATCH] ice_main, ice_lib: Use irq_update_affinity_hint
This commit makes the ice device driver use the irq_update_affinity_hint
function instead of the irq_set_affinity_hint function. This is done
because the latter function sets the IRQ CPU affinities, whereas the
former does not, and this allows the use of the default IRQ affinity CPU
mask provided via the irqaffinity= kernel command line option.
Please note that this patch was not cherry-picked from an upstream
commit. The changes have been inspired by the i40e and iavf device
driver patches in the following patch series:
https://lore.kernel.org/netdev/20210903152430.244937-1-nitesh@redhat.com/t/#u
The aforementioned patches have been mainlined as of this writing with
the following merge commit by Linus Torvalds:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=147cc5838c0f5c76e908b816e924ca378e0d4735
And the i40e and iavf patches are accessible at:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34c54d1739c2cdf2e4437b74e6da269147f4987
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0f9744f4ed539f2e847d7ed41993b243e3ba5cff
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
src/ice_lib.c | 2 +-
src/ice_main.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/ice_lib.c b/src/ice_lib.c
index 889972052be7..6e50a9dc9ef4 100644
--- a/src/ice_lib.c
+++ b/src/ice_lib.c
@@ -2883,7 +2883,7 @@ void ice_vsi_free_irq(struct ice_vsi *vsi)
irq_set_affinity_notifier(irq_num, NULL);
/* clear the affinity_mask in the IRQ descriptor */
- irq_set_affinity_hint(irq_num, NULL);
+ irq_update_affinity_hint(irq_num, NULL);
synchronize_irq(irq_num);
devm_free_irq(ice_pf_to_dev(pf), irq_num, vsi->q_vectors[i]);
}
diff --git a/src/ice_main.c b/src/ice_main.c
index 97e754bc5e11..802d4912a574 100644
--- a/src/ice_main.c
+++ b/src/ice_main.c
@@ -3384,8 +3384,8 @@ static int ice_vsi_req_irq_msix(struct ice_vsi *vsi, char *basename)
irq_set_affinity_notifier(irq_num, affinity_notify);
}
- /* assign the mask for this irq */
- irq_set_affinity_hint(irq_num, &q_vector->affinity_mask);
+ /* assign the affinity hint for this irq */
+ irq_update_affinity_hint(irq_num, &q_vector->affinity_mask);
}
vsi->irqs_ready = true;
@@ -3397,7 +3397,7 @@ free_q_irqs:
irq_num = pf->msix_entries[base + vector].vector;
if (!IS_ENABLED(CONFIG_RFS_ACCEL))
irq_set_affinity_notifier(irq_num, NULL);
- irq_set_affinity_hint(irq_num, NULL);
+ irq_update_affinity_hint(irq_num, NULL);
devm_free_irq(dev, irq_num, &vsi->q_vectors[vector]);
}
return err;
--
2.29.2

View File

@ -1,2 +1,3 @@
0001-ice_xsk-Avoid-dependency-on-napi_busy_loop-with-PREE.patch
0001-check_aux_bus-Look-for-kernel-headers-in-the-right-l.patch
0002-ice_main-ice_lib-Use-irq_update_affinity_hint.patch
0001-intel-ice-pass-linux-common-header-to-check_aux_bus.patch

View File

@ -27,7 +27,9 @@
WITH_MOD_SIGN ?= 1
kheaders_name=$(shell ls /usr/src | grep linux@KERNEL_TYPE@-headers | grep amd64)
kheaders_common=$(shell ls /usr/src | grep linux@KERNEL_TYPE@-headers | grep common)
export KSRC=/usr/src/$(kheaders_name)
export KSRC_COMMON=/usr/src/$(kheaders_common)
kversion=$(shell echo $(kheaders_name) | sed 's/linux@KERNEL_TYPE@-headers-//g')
kmod_name=ice
version=$(shell dpkg-parsechangelog | sed -n 's/^Version: *\([^-]\+\)-.\+/\1/p')
@ -45,7 +47,6 @@ endif
override_dh_auto_install:
dh_install src/$(kmod_name).ko /lib/modules/$(kversion)/extra/$(kmod_name)/
dh_install src/auxiliary.ko /lib/modules/$(kversion)/extra/$(kmod_name)/
dh_install pci.updates $(_defaultdocdir)/kmod-$(kmod_name)-$(version)/
dh_install README $(_defaultdocdir)/kmod-$(kmod_name)-$(version)/
dh_install $(kmod_name).7 $(_mandir)/man7/
@ -62,9 +63,6 @@ ifeq ($(WITH_MOD_SIGN),1)
@echo "Sign the modules!"
/usr/lib/linux@KERNEL_TYPE@-kbuild-*/scripts/sign-file sha256 $(privkey) $(pubkey) \
./debian/$(pkg_name)/lib/modules/$(kversion)/extra/$(kmod_name)/$(kmod_name).ko
/usr/lib/linux@KERNEL_TYPE@-kbuild-*/scripts/sign-file sha256 $(privkey) $(pubkey) \
./debian/$(pkg_name)/lib/modules/$(kversion)/extra/$(kmod_name)/auxiliary.ko
endif
override_dh_auto_build:

View File

@ -0,0 +1,91 @@
From e5d69db1083481aef4ea64b504c294929c7422d9 Mon Sep 17 00:00:00 2001
From: "M. Vefa Bicakci" <vefa.bicakci@windriver.com>
Date: Fri, 14 Jan 2022 16:26:29 -0500
Subject: [PATCH] mlx5: pci_irq: Use irq_update_affinity_hint
This commit applies a patch that modifies the mlx5 driver so that it
uses the irq_update_affinity_hint function instead of the
irq_set_affinity_hint function. The former only sets the hint, whereas
the latter sets both the hint and the IRQ affinity.
The intent of the patch is to allow the user-specified IRQ affinity (via
the irqaffinity= command line argument) take effect for the IRQs set up
by the mlx5 device driver.
(Please see the description of the applied patch for more information.)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
...pci_irq-Use-irq_update_affinity_hint.patch | 60 +++++++++++++++++++
1 file changed, 60 insertions(+)
create mode 100644 source/backports/1000-mlx5-pci_irq-Use-irq_update_affinity_hint.patch
diff --git a/source/backports/1000-mlx5-pci_irq-Use-irq_update_affinity_hint.patch b/source/backports/1000-mlx5-pci_irq-Use-irq_update_affinity_hint.patch
new file mode 100644
index 000000000000..f1122af264eb
--- /dev/null
+++ b/source/backports/1000-mlx5-pci_irq-Use-irq_update_affinity_hint.patch
@@ -0,0 +1,60 @@
+From 3884feaf05e9b1003ab83ab76fbfdf9a188c4a19 Mon Sep 17 00:00:00 2001
+From: "M. Vefa Bicakci" <vefa.bicakci@windriver.com>
+Date: Fri, 14 Jan 2022 16:26:29 -0500
+Subject: [PATCH] mlx5: pci_irq: Use irq_update_affinity_hint
+
+The StarlingX kernel was patched to deprecate irq_set_affinity_hint
+by cherry-picking the patches at:
+ https://lore.kernel.org/netdev/20210903152430.244937-1-nitesh@redhat.com/t/#u
+
+These patches have been mainlined as of this writing, with the following
+merge commit by Linus Torvalds:
+ https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=147cc5838c0f5c76e908b816e924ca378e0d4735
+
+This commit modifies the mlx5 driver so that it uses the
+irq_update_affinity_hint function instead of the irq_set_affinity_hint
+function. The former only sets the hint, whereas the latter sets both
+the hint and the IRQ affinity.
+
+Please note that this is a divergence from the aforementioned patch
+series, which make mlx5 use irq_set_affinity_and_hint, which currently
+behaves in the same way as irq_set_affinity_hint. The intent with
+diverging from mainline is to allow the user-specified IRQ affinity (via
+the irqaffinity= command line argument) take effect for the IRQs
+set up by the mlx5 device driver.
+
+The mlx5 commit in mainline is accessible at:
+ https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7451e9ea8e2055af39afe7ff39a5f68d8ec6b98d
+
+Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
+index 09d0ce8061f3..db7472d10fb6 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
+@@ -237,8 +237,8 @@ static int set_comp_irq_affinity_hint(struct mlx5_core_dev *mdev, int i)
+ cpumask_set_cpu(cpumask_local_spread(i, mdev->priv.numa_node),
+ irq->mask);
+ if (IS_ENABLED(CONFIG_SMP) &&
+- irq_set_affinity_hint(irqn, irq->mask))
+- mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x",
++ irq_update_affinity_hint(irqn, irq->mask))
++ mlx5_core_warn(mdev, "irq_update_affinity_hint failed, irq 0x%.4x",
+ irqn);
+
+ return 0;
+@@ -261,7 +261,7 @@ static void clear_comp_irq_affinity_hint(struct mlx5_core_dev *mdev, int i)
+ msix = priv->msix_arr;
+ irqn = msix[vecidx].vector;
+ #endif
+- irq_set_affinity_hint(irqn, NULL);
++ irq_update_affinity_hint(irqn, NULL);
+ free_cpumask_var(irq->mask);
+ }
+
+--
+2.29.2
+
--
2.29.2

View File

@ -1 +1,2 @@
0001-implicit-declaration-of-function-__is_constexpr.patch
0002-mlx5-pci_irq-Use-irq_update_affinity_hint.patch

View File

@ -0,0 +1,380 @@
From 9b4b48ccfccbdaa7ea1c8631a131d4c57a5f6e54 Mon Sep 17 00:00:00 2001
From: Li Zhou <li.zhou@windriver.com>
Date: Thu, 7 Apr 2022 15:28:48 +0800
Subject: [PATCH] Debian: align config file with stx centos
Porting below commits from stx centos to stx debian for kernel-rt:
6fe8d6083263 kernel: Disable NVMe multi-path kconfig option
c9cdb902767d Fixup recent kconfig cleanup
8551799e01ca Resolve v5.10 kernel configuration file differences
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
debian/config/amd64/none/config | 102 +++++++++++++++-----------------
1 file changed, 47 insertions(+), 55 deletions(-)
diff --git a/debian/config/amd64/none/config b/debian/config/amd64/none/config
index e329ad0..1264175 100644
--- a/debian/config/amd64/none/config
+++ b/debian/config/amd64/none/config
@@ -133,7 +133,7 @@ CONFIG_RCU_NOCB_CPU=y
CONFIG_BUILD_BIN2C=y
# CONFIG_IKCONFIG is not set
# CONFIG_IKHEADERS is not set
-CONFIG_LOG_BUF_SHIFT=20
+CONFIG_LOG_BUF_SHIFT=18
CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
@@ -361,11 +361,11 @@ CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_DMI=y
# CONFIG_GART_IOMMU is not set
-CONFIG_MAXSMP=y
-CONFIG_NR_CPUS_RANGE_BEGIN=8192
-CONFIG_NR_CPUS_RANGE_END=8192
-CONFIG_NR_CPUS_DEFAULT=8192
-CONFIG_NR_CPUS=8192
+# CONFIG_MAXSMP is not set
+CONFIG_NR_CPUS_RANGE_BEGIN=2
+CONFIG_NR_CPUS_RANGE_END=512
+CONFIG_NR_CPUS_DEFAULT=64
+CONFIG_NR_CPUS=256
CONFIG_SCHED_SMT=y
CONFIG_SCHED_MC=y
CONFIG_SCHED_MC_PRIO=y
@@ -408,7 +408,7 @@ CONFIG_AMD_MEM_ENCRYPT=y
CONFIG_NUMA=y
CONFIG_AMD_NUMA=y
CONFIG_X86_64_ACPI_NUMA=y
-CONFIG_NUMA_EMU=y
+# CONFIG_NUMA_EMU is not set
CONFIG_NODES_SHIFT=10
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
@@ -430,8 +430,8 @@ CONFIG_ARCH_RANDOM=y
CONFIG_X86_SMAP=y
CONFIG_X86_UMIP=y
CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y
-# CONFIG_X86_INTEL_TSX_MODE_OFF is not set
-CONFIG_X86_INTEL_TSX_MODE_ON=y
+CONFIG_X86_INTEL_TSX_MODE_OFF=y
+# CONFIG_X86_INTEL_TSX_MODE_ON is not set
# CONFIG_X86_INTEL_TSX_MODE_AUTO is not set
CONFIG_EFI=y
CONFIG_EFI_STUB=y
@@ -498,9 +498,7 @@ CONFIG_PM_SLEEP_DEBUG=y
# CONFIG_DPM_WATCHDOG is not set
# CONFIG_PM_TRACE_RTC is not set
CONFIG_PM_CLK=y
-CONFIG_PM_GENERIC_DOMAINS=y
# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
-CONFIG_PM_GENERIC_DOMAINS_SLEEP=y
# CONFIG_ENERGY_MODEL is not set
CONFIG_ARCH_SUPPORTS_ACPI=y
CONFIG_ACPI=y
@@ -694,7 +692,7 @@ CONFIG_HAVE_KVM_NO_POLL=y
CONFIG_KVM_XFER_TO_GUEST_WORK=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=m
-CONFIG_KVM_WERROR=y
+# CONFIG_KVM_WERROR is not set
CONFIG_KVM_INTEL=m
CONFIG_KVM_AMD=m
CONFIG_KVM_AMD_SEV=y
@@ -716,6 +714,7 @@ CONFIG_OPROFILE_NMI_TIMER=y
CONFIG_JUMP_LABEL=y
# CONFIG_STATIC_KEYS_SELFTEST is not set
# CONFIG_STATIC_CALL_SELFTEST is not set
+CONFIG_UPROBES=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_USER_RETURN_NOTIFIER=y
@@ -972,10 +971,10 @@ CONFIG_ZPOOL=y
CONFIG_ZBUD=y
# CONFIG_Z3FOLD is not set
CONFIG_ZSMALLOC=y
-CONFIG_ZSMALLOC_STAT=y
+# CONFIG_ZSMALLOC_STAT is not set
CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
-CONFIG_IDLE_PAGE_TRACKING=y
+# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set
+# CONFIG_IDLE_PAGE_TRACKING is not set
CONFIG_ARCH_HAS_PTE_DEVMAP=y
CONFIG_VMAP_PFN=y
CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y
@@ -1431,7 +1430,7 @@ CONFIG_IP6_NF_TARGET_NPT=m
CONFIG_NF_DEFRAG_IPV6=m
CONFIG_NF_TABLES_BRIDGE=m
-# CONFIG_NFT_BRIDGE_META is not set
+CONFIG_NFT_BRIDGE_META=m
CONFIG_NFT_BRIDGE_REJECT=m
CONFIG_NF_LOG_BRIDGE=m
# CONFIG_NF_CONNTRACK_BRIDGE is not set
@@ -1699,7 +1698,7 @@ CONFIG_CAN_ESD_USB2=m
CONFIG_CAN_KVASER_USB=m
# CONFIG_CAN_MCBA_USB is not set
CONFIG_CAN_PEAK_USB=m
-CONFIG_CAN_UCAN=m
+# CONFIG_CAN_UCAN is not set
# end of CAN USB interfaces
# CONFIG_CAN_DEBUG_DEVICES is not set
@@ -1829,6 +1828,7 @@ CONFIG_VMD=y
#
# Generic Driver Options
#
+CONFIG_AUXILIARY_BUS=y
# CONFIG_UEVENT_HELPER is not set
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
@@ -2005,7 +2005,7 @@ CONFIG_BLK_DEV_RBD=m
#
CONFIG_NVME_CORE=m
CONFIG_BLK_DEV_NVME=m
-CONFIG_NVME_MULTIPATH=y
+# CONFIG_NVME_MULTIPATH is not set
# CONFIG_NVME_HWMON is not set
CONFIG_NVME_FABRICS=m
CONFIG_NVME_FC=m
@@ -2137,7 +2137,7 @@ CONFIG_SCSI_AACRAID=y
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC79XX is not set
CONFIG_SCSI_AIC94XX=y
-CONFIG_AIC94XX_DEBUG=y
+# CONFIG_AIC94XX_DEBUG is not set
CONFIG_SCSI_MVSAS=y
CONFIG_SCSI_MVSAS_DEBUG=y
# CONFIG_SCSI_MVSAS_TASKLET is not set
@@ -2354,7 +2354,7 @@ CONFIG_FUSION=y
CONFIG_FUSION_SPI=m
# CONFIG_FUSION_FC is not set
CONFIG_FUSION_SAS=y
-CONFIG_FUSION_MAX_SGE=128
+CONFIG_FUSION_MAX_SGE=40
# CONFIG_FUSION_CTL is not set
CONFIG_FUSION_LOGGING=y
@@ -2483,7 +2483,7 @@ CONFIG_BE2NET_LANCER=y
CONFIG_BE2NET_SKYHAWK=y
# CONFIG_NET_VENDOR_EZCHIP is not set
CONFIG_NET_VENDOR_GOOGLE=y
-# CONFIG_GVE is not set
+CONFIG_GVE=m
CONFIG_NET_VENDOR_HUAWEI=y
CONFIG_HINIC=m
# CONFIG_NET_VENDOR_I825XX is not set
@@ -2512,7 +2512,11 @@ CONFIG_IGC=m
# CONFIG_JME is not set
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MELLANOX is not set
-# CONFIG_NET_VENDOR_MICREL is not set
+CONFIG_NET_VENDOR_MICREL=y
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_KSZ884X_PCI is not set
# CONFIG_NET_VENDOR_MICROCHIP is not set
# CONFIG_NET_VENDOR_MICROSEMI is not set
CONFIG_NET_VENDOR_MYRI=y
@@ -2617,16 +2621,16 @@ CONFIG_MICROSEMI_PHY=m
# CONFIG_NATIONAL_PHY is not set
# CONFIG_NXP_TJA11XX_PHY is not set
# CONFIG_QSEMI_PHY is not set
-CONFIG_REALTEK_PHY=m
+CONFIG_REALTEK_PHY=y
CONFIG_RENESAS_PHY=m
CONFIG_ROCKCHIP_PHY=m
# CONFIG_SMSC_PHY is not set
# CONFIG_STE10XP is not set
CONFIG_TERANETICS_PHY=m
CONFIG_DP83822_PHY=m
-CONFIG_DP83TC811_PHY=m
+# CONFIG_DP83TC811_PHY is not set
CONFIG_DP83848_PHY=m
-CONFIG_DP83867_PHY=m
+# CONFIG_DP83867_PHY is not set
# CONFIG_DP83869_PHY is not set
# CONFIG_VITESSE_PHY is not set
CONFIG_XILINX_GMII2RGMII=m
@@ -2636,10 +2640,9 @@ CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVRES=y
# CONFIG_MDIO_BITBANG is not set
CONFIG_MDIO_BCM_UNIMAC=m
-CONFIG_MDIO_CAVIUM=m
# CONFIG_MDIO_MVUSB is not set
-CONFIG_MDIO_MSCC_MIIM=m
-CONFIG_MDIO_THUNDER=m
+# CONFIG_MDIO_MSCC_MIIM is not set
+# CONFIG_MDIO_THUNDER is not set
#
# MDIO Multiplexers
@@ -3765,7 +3768,7 @@ CONFIG_DRM_AMDGPU=m
#
# ACP (Audio CoProcessor) Configuration
#
-CONFIG_DRM_AMD_ACP=y
+# CONFIG_DRM_AMD_ACP is not set
# end of ACP (Audio CoProcessor) Configuration
#
@@ -4435,7 +4438,7 @@ CONFIG_INFINIBAND_VIRT_DMA=y
# CONFIG_INFINIBAND_BNXT_RE is not set
# CONFIG_INFINIBAND_QEDR is not set
# CONFIG_INFINIBAND_RDMAVT is not set
-CONFIG_RDMA_RXE=m
+# CONFIG_RDMA_RXE is not set
# CONFIG_RDMA_SIW is not set
# CONFIG_INFINIBAND_IPOIB is not set
# CONFIG_INFINIBAND_OPA_VNIC is not set
@@ -5341,14 +5344,7 @@ CONFIG_NVMEM_SYSFS=y
# end of HW tracing support
# CONFIG_FPGA is not set
-CONFIG_TEE=m
-
-#
-# TEE drivers
-#
-CONFIG_AMDTEE=m
-# end of TEE drivers
-
+# CONFIG_TEE is not set
# CONFIG_UNISYS_VISORBUS is not set
# CONFIG_SIOX is not set
# CONFIG_SLIMBUS is not set
@@ -5656,11 +5652,11 @@ CONFIG_SECURITY_WRITABLE_HOOKS=y
CONFIG_SECURITYFS=y
CONFIG_SECURITY_NETWORK=y
CONFIG_PAGE_TABLE_ISOLATION=y
-CONFIG_SECURITY_INFINIBAND=y
+# CONFIG_SECURITY_INFINIBAND is not set
CONFIG_SECURITY_NETWORK_XFRM=y
# CONFIG_SECURITY_PATH is not set
CONFIG_INTEL_TXT=y
-CONFIG_LSM_MMAP_MIN_ADDR=65535
+CONFIG_LSM_MMAP_MIN_ADDR=65536
CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
CONFIG_HARDENED_USERCOPY=y
CONFIG_HARDENED_USERCOPY_FALLBACK=y
@@ -5672,7 +5668,7 @@ CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_SECURITY_SELINUX_DEVELOP=y
CONFIG_SECURITY_SELINUX_AVC_STATS=y
-CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0
CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS=9
CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE=256
# CONFIG_SECURITY_SMACK is not set
@@ -5724,7 +5720,7 @@ CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RNG_DEFAULT=m
+CONFIG_CRYPTO_RNG_DEFAULT=y
CONFIG_CRYPTO_AKCIPHER2=y
CONFIG_CRYPTO_AKCIPHER=y
CONFIG_CRYPTO_KPP2=y
@@ -5765,7 +5761,7 @@ CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_CHACHA20POLY1305=m
# CONFIG_CRYPTO_AEGIS128 is not set
# CONFIG_CRYPTO_AEGIS128_AESNI_SSE2 is not set
-CONFIG_CRYPTO_SEQIV=m
+CONFIG_CRYPTO_SEQIV=y
CONFIG_CRYPTO_ECHAINIV=m
#
@@ -5836,8 +5832,6 @@ CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m
CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_AES_TI is not set
CONFIG_CRYPTO_AES_NI_INTEL=y
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_BLOWFISH_COMMON=m
# CONFIG_CRYPTO_BLOWFISH_X86_64 is not set
@@ -5853,17 +5847,14 @@ CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_DES3_EDE_X86_64=m
CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_KHAZAD=m
# CONFIG_CRYPTO_SALSA20 is not set
CONFIG_CRYPTO_CHACHA20=m
CONFIG_CRYPTO_CHACHA20_X86_64=m
-CONFIG_CRYPTO_SEED=m
CONFIG_CRYPTO_SERPENT=m
# CONFIG_CRYPTO_SERPENT_SSE2_X86_64 is not set
# CONFIG_CRYPTO_SERPENT_AVX_X86_64 is not set
# CONFIG_CRYPTO_SERPENT_AVX2_X86_64 is not set
# CONFIG_CRYPTO_SM4 is not set
-CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_TWOFISH_COMMON=m
# CONFIG_CRYPTO_TWOFISH_X86_64 is not set
@@ -5896,7 +5887,7 @@ CONFIG_CRYPTO_USER_API=y
CONFIG_CRYPTO_USER_API_RNG=y
# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set
CONFIG_CRYPTO_USER_API_AEAD=y
-CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y
+# CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE is not set
# CONFIG_CRYPTO_STATS is not set
CONFIG_CRYPTO_HASH_INFO=y
@@ -6031,7 +6022,6 @@ CONFIG_DMA_COHERENT_POOL=y
# CONFIG_DMA_API_DEBUG is not set
CONFIG_SGL_ALLOC=y
CONFIG_CHECK_SIGNATURE=y
-CONFIG_CPUMASK_OFFSTACK=y
CONFIG_CPU_RMAP=y
CONFIG_DQL=y
CONFIG_GLOB=y
@@ -6091,11 +6081,11 @@ CONFIG_DEBUG_INFO_DWARF4=y
# CONFIG_DEBUG_INFO_BTF is not set
# CONFIG_GDB_SCRIPTS is not set
CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_FRAME_WARN=8192
+CONFIG_FRAME_WARN=2048
CONFIG_STRIP_ASM_SYMS=y
# CONFIG_READABLE_ASM is not set
# CONFIG_HEADERS_INSTALL is not set
-CONFIG_DEBUG_SECTION_MISMATCH=y
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
CONFIG_SECTION_MISMATCH_WARN_ONLY=y
# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_32B is not set
CONFIG_STACK_VALIDATION=y
@@ -6121,7 +6111,7 @@ CONFIG_HAVE_ARCH_KCSAN=y
# end of Generic Kernel Debugging Instruments
CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_MISC=y
+# CONFIG_DEBUG_MISC is not set
#
# Memory Debugging
@@ -6191,7 +6181,7 @@ CONFIG_SCHEDSTATS=y
# end of Scheduler Debugging
# CONFIG_DEBUG_TIMEKEEPING is not set
-CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_PREEMPT is not set
#
# Lock Debugging (spinlocks, mutexes, etc...)
@@ -6280,8 +6270,10 @@ CONFIG_FTRACE_SYSCALLS=y
CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
CONFIG_BLK_DEV_IO_TRACE=y
-# CONFIG_UPROBE_EVENTS is not set
+CONFIG_UPROBE_EVENTS=y
+CONFIG_BPF_EVENTS=y
CONFIG_DYNAMIC_EVENTS=y
+CONFIG_PROBE_EVENTS=y
CONFIG_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_MAP=y
CONFIG_SYNTH_EVENTS=y
--
2.17.1

View File

@ -3,3 +3,4 @@
0003-kernel-rt-Add-a-kernel-config-file-for-stx-debian.patch
0004-kernel-rt-Adapt-the-debian-folder-for-new-source.patch
0005-kernel-modules-sign-kernel-modules.patch
0006-Debian-align-config-file-with-stx-centos.patch

View File

@ -1,7 +1,7 @@
From 3cc07f73b18833769e4b907734740c0f90f06938 Mon Sep 17 00:00:00 2001
From 5fba1536bd24bc77ef0d6b2516fefcff69d7cf59 Mon Sep 17 00:00:00 2001
From: Chris Friesen <chris.friesen@windriver.com>
Date: Tue, 24 Nov 2015 16:27:28 -0500
Subject: [PATCH 03/11] affine compute kernel threads
Subject: [PATCH] affine compute kernel threads
This is a kernel enhancement to configure the cpu affinity of kernel
threads via kernel boot option kthread_cpus=<cpulist>. The compute
@ -31,16 +31,16 @@ Signed-off-by: Vefa Bicakci <vefa.bicakci@windriver.com>
[jm: Adapted the patch for context changes.]
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
---
.../admin-guide/kernel-parameters.txt | 10 ++++++++++
.../admin-guide/kernel-parameters.txt | 10 ++++++++
include/linux/cpumask.h | 3 +++
init/main.c | 2 ++
kernel/cpu.c | 19 +++++++++++++++++++
kernel/cpu.c | 23 +++++++++++++++++++
kernel/kthread.c | 4 ++--
kernel/umh.c | 3 +++
6 files changed, 39 insertions(+), 2 deletions(-)
6 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index a19a3005b..6f79c718a 100644
index a19a3005b545..6f79c718ae4f 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2223,6 +2223,16 @@
@ -61,7 +61,7 @@ index a19a3005b..6f79c718a 100644
and kernel address spaces.
Default: enabled on cores which need mitigation.
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 383684e30..8fcc67ea3 100644
index 383684e30f12..8fcc67ea3d8c 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -55,6 +55,7 @@ extern unsigned int nr_cpu_ids;
@ -86,7 +86,7 @@ index 383684e30..8fcc67ea3 100644
extern atomic_t __num_online_cpus;
diff --git a/init/main.c b/init/main.c
index db693781a..4e7777bda 100644
index db693781a12f..4e7777bdab6e 100644
--- a/init/main.c
+++ b/init/main.c
@@ -1536,6 +1536,8 @@ static noinline void __init kernel_init_freeable(void)
@ -99,10 +99,10 @@ index db693781a..4e7777bda 100644
console_on_rootfs();
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 016f2d068..5f9bf198b 100644
index 016f2d0686b6..6783db02e9ae 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -2505,6 +2505,25 @@ EXPORT_SYMBOL(__cpu_active_mask);
@@ -2505,6 +2505,29 @@ EXPORT_SYMBOL(__cpu_active_mask);
atomic_t __num_online_cpus __read_mostly;
EXPORT_SYMBOL(__num_online_cpus);
@ -112,15 +112,19 @@ index 016f2d068..5f9bf198b 100644
+
+static int __init kthread_setup(char *str)
+{
+ struct cpumask tmp_mask;
+ cpumask_var_t tmp_mask;
+ int err;
+
+ err = cpulist_parse(str, &tmp_mask);
+
+ alloc_bootmem_cpumask_var(&tmp_mask);
+
+ err = cpulist_parse(str, tmp_mask);
+ if (!err)
+ cpumask_copy(&__cpu_kthread_mask, &tmp_mask);
+ cpumask_copy(&__cpu_kthread_mask, tmp_mask);
+ else
+ pr_err("Cannot parse 'kthread_cpus=%s'; error %d\n", str, err);
+
+ pr_err("Cannot parse 'kthread_cpus=%s'; error %d\n", str, err);
+
+ free_bootmem_cpumask_var(tmp_mask);
+
+ return 1;
+}
+__setup("kthread_cpus=", kthread_setup);
@ -129,7 +133,7 @@ index 016f2d068..5f9bf198b 100644
{
cpumask_copy(&__cpu_present_mask, src);
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 3ce6a31db..683008e94 100644
index 3ce6a31db7b4..683008e94fd4 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -300,7 +300,7 @@ static int kthread(void *_create)
@ -151,7 +155,7 @@ index 3ce6a31db..683008e94 100644
current->flags |= PF_NOFREEZE;
diff --git a/kernel/umh.c b/kernel/umh.c
index 3f646613a..e5027cee4 100644
index 3f646613a9d3..e5027cee43f7 100644
--- a/kernel/umh.c
+++ b/kernel/umh.c
@@ -80,6 +80,9 @@ static int call_usermodehelper_exec_async(void *data)
@ -165,5 +169,5 @@ index 3f646613a..e5027cee4 100644
* Our parent (unbound workqueue) runs with elevated scheduling
* priority. Avoid propagating that into the userspace child.
--
2.17.1
2.29.2

View File

@ -0,0 +1,61 @@
From 6039b821dbe26c7708537e07276316dca36c1c0f Mon Sep 17 00:00:00 2001
From: "M. Vefa Bicakci" <vefa.bicakci@windriver.com>
Date: Thu, 9 Sep 2021 04:56:46 -0400
Subject: [PATCH] workqueue: Affine rescuer threads and unbound wqs
This commit ensures that workqueue rescuer threads are affined to the
platform CPUs specified by the "kthread_cpus" kernel argument. Prior to
this commit, rescuer threads could be bound to any CPU. Rescuer threads
are described in "kernel/workqueue.c" as follows:
"Regular work processing on a pool may block trying to create a new
worker which uses GFP_KERNEL allocation which has slight chance of
developing into deadlock if some works currently on the same queue
need to be processed to satisfy the GFP_KERNEL allocation. This is
the problem rescuer solves.
When such condition is possible, the pool summons rescuers of all
workqueues which have works queued on the pool and let them process
those works so that forward progress can be guaranteed."
This commit also affines unbound workqueues to the platform CPUs instead
of the housekeeping CPUs, because the latter can be a superset of the
former.
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
---
kernel/workqueue.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 1a4151c6faa6..3e3bd8d75f3c 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -4242,7 +4242,7 @@ static int init_rescuer(struct workqueue_struct *wq)
}
wq->rescuer = rescuer;
- kthread_bind_mask(rescuer->task, cpu_possible_mask);
+ kthread_bind_mask(rescuer->task, cpu_kthread_mask);
wake_up_process(rescuer->task);
return 0;
@@ -5941,13 +5941,12 @@ static void __init wq_numa_init(void)
void __init workqueue_init_early(void)
{
int std_nice[NR_STD_WORKER_POOLS] = { 0, HIGHPRI_NICE_LEVEL };
- int hk_flags = HK_FLAG_DOMAIN | HK_FLAG_WQ;
int i, cpu;
BUILD_BUG_ON(__alignof__(struct pool_workqueue) < __alignof__(long long));
BUG_ON(!alloc_cpumask_var(&wq_unbound_cpumask, GFP_KERNEL));
- cpumask_copy(wq_unbound_cpumask, housekeeping_cpumask(hk_flags));
+ cpumask_copy(wq_unbound_cpumask, cpu_kthread_mask);
pwq_cache = KMEM_CACHE(pool_workqueue, SLAB_PANIC);
--
2.29.2

View File

@ -0,0 +1,64 @@
From e21cab0b7f1a6634ee57950600b68f6df960e3f5 Mon Sep 17 00:00:00 2001
From: "Paul E. McKenney" <paulmck@kernel.org>
Date: Tue, 20 Jul 2021 06:16:27 -0700
Subject: [PATCH] rcu: Mark accesses to rcu_state.n_force_qs
This commit marks accesses to the rcu_state.n_force_qs. These data
races are hard to make happen, but syzkaller was equal to the task.
Reported-by: syzbot+e08a83a1940ec3846cd5@syzkaller.appspotmail.com
Acked-by: Marco Elver <elver@google.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
(cherry picked from commit 2431774f04d1050292054c763070021bade7b151)
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
---
kernel/rcu/tree.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 4cc5af7f2b91..30cb9af8284c 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -1890,7 +1890,7 @@ static void rcu_gp_fqs(bool first_time)
struct rcu_node *rnp = rcu_get_root();
WRITE_ONCE(rcu_state.gp_activity, jiffies);
- rcu_state.n_force_qs++;
+ WRITE_ONCE(rcu_state.n_force_qs, rcu_state.n_force_qs + 1);
if (first_time) {
/* Collect dyntick-idle snapshots. */
force_qs_rnp(dyntick_save_progress_counter);
@@ -2532,7 +2532,7 @@ static void rcu_do_batch(struct rcu_data *rdp)
/* Reset ->qlen_last_fqs_check trigger if enough CBs have drained. */
if (count == 0 && rdp->qlen_last_fqs_check != 0) {
rdp->qlen_last_fqs_check = 0;
- rdp->n_force_qs_snap = rcu_state.n_force_qs;
+ rdp->n_force_qs_snap = READ_ONCE(rcu_state.n_force_qs);
} else if (count < rdp->qlen_last_fqs_check - qhimark)
rdp->qlen_last_fqs_check = count;
@@ -2878,10 +2878,10 @@ static void __call_rcu_core(struct rcu_data *rdp, struct rcu_head *head,
} else {
/* Give the grace period a kick. */
rdp->blimit = DEFAULT_MAX_RCU_BLIMIT;
- if (rcu_state.n_force_qs == rdp->n_force_qs_snap &&
+ if (READ_ONCE(rcu_state.n_force_qs) == rdp->n_force_qs_snap &&
rcu_segcblist_first_pend_cb(&rdp->cblist) != head)
rcu_force_quiescent_state();
- rdp->n_force_qs_snap = rcu_state.n_force_qs;
+ rdp->n_force_qs_snap = READ_ONCE(rcu_state.n_force_qs);
rdp->qlen_last_fqs_check = rcu_segcblist_n_cbs(&rdp->cblist);
}
}
@@ -3988,7 +3988,7 @@ int rcutree_prepare_cpu(unsigned int cpu)
/* Set up local state, ensuring consistent view of global state. */
raw_spin_lock_irqsave_rcu_node(rnp, flags);
rdp->qlen_last_fqs_check = 0;
- rdp->n_force_qs_snap = rcu_state.n_force_qs;
+ rdp->n_force_qs_snap = READ_ONCE(rcu_state.n_force_qs);
rdp->blimit = blimit;
if (rcu_segcblist_empty(&rdp->cblist) && /* No early-boot CBs? */
!rcu_segcblist_is_offloaded(&rdp->cblist))
--
2.31.1

View File

@ -0,0 +1,45 @@
From 21e034adb9df3581fda926a29b3a11bda38ba93b Mon Sep 17 00:00:00 2001
From: "Paul E. McKenney" <paulmck@kernel.org>
Date: Fri, 17 Sep 2021 15:04:48 -0700
Subject: [PATCH] rcu: Tighten rcu_advance_cbs_nowake() checks
Currently, rcu_advance_cbs_nowake() checks that a grace period is in
progress, however, that grace period could end just after the check.
This commit rechecks that a grace period is still in progress the lock.
The grace period cannot end while the current CPU's rcu_node structure's
->lock is held, thus avoiding false positives from the WARN_ON_ONCE().
As Daniel Vacek noted, it is not necessary for the rcu_node structure
to have a CPU that has not yet passed through its quiescent state.
Tested-By: Guillaume Morin <guillaume@morinfr.org>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
(Cherry pick from https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/
linux-rcu.git/commit/?h=rcu/next&id=325a2030b90376d179a129794e2fae2b24d73923)
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
---
kernel/rcu/tree.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index ef8d36f580fc..8706b30c2ac8 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -1590,10 +1590,11 @@ static void __maybe_unused rcu_advance_cbs_nowake(struct rcu_node *rnp,
struct rcu_data *rdp)
{
rcu_lockdep_assert_cblist_protected(rdp);
- if (!rcu_seq_state(rcu_seq_current(&rnp->gp_seq)) ||
- !raw_spin_trylock_rcu_node(rnp))
+ if (!rcu_seq_state(rcu_seq_current(&rnp->gp_seq)) || !raw_spin_trylock_rcu_node(rnp))
return;
- WARN_ON_ONCE(rcu_advance_cbs(rnp, rdp));
+ // The grace period cannot end while we hold the rcu_node lock.
+ if (rcu_seq_state(rcu_seq_current(&rnp->gp_seq)))
+ WARN_ON_ONCE(rcu_advance_cbs(rnp, rdp));
raw_spin_unlock_rcu_node(rnp);
}
--
2.31.1

View File

@ -0,0 +1,167 @@
From 42f1ccc21f873a27c125a4e1aa3cb70a2336aa14 Mon Sep 17 00:00:00 2001
From: Jiping Ma <jiping.ma2@windriver.com>
Date: Wed, 8 Dec 2021 17:49:56 -0800
Subject: [PATCH] Revert "scsi: sd: Inline sd_probe_part2()"
This reverts commit 82a54da641f3cacfa31db36fc58a5e903f804c22.
Merge conflicts were encountered when reverting this commit, which
inlines sd_probe_part2() into sd_probe(). However, the inlined parts
of sd_probe_part2() have since been modified. To avoid a difference
in behaviour, the updated code was relocated to sd_probe_part2().
The inlined code has been modified as follows since the inlining
happened:
The following code was added
if (sdp->rpm_autosuspend) {
pm_runtime_set_autosuspend_delay(dev,
sdp->host->hostt->rpm_autosuspend_delay);
}
between the following line
blk_pm_runtime_init(sdp->request_queue, dev);
and the following line
device_add_disk(dev, gd, NULL);
In addition, init_opal_dev() is now passed the pointer "sdkp"
instead of "sdp" as the first argument. This commit ensures that
these two changes were accounted for when reverting the inlining
of sd_probe_part2().
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
---
drivers/scsi/sd.c | 111 ++++++++++++++++++++++++++--------------------
1 file changed, 63 insertions(+), 48 deletions(-)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 56e291708587..d1d27516fc6a 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -3364,6 +3364,68 @@ static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen)
return 0;
}
+static void sd_probe_part2(struct scsi_disk *sdkp)
+{
+ struct scsi_device *sdp;
+ struct gendisk *gd;
+ u32 index;
+ struct device *dev;
+
+ sdp = sdkp->device;
+ gd = sdkp->disk;
+ index = sdkp->index;
+ dev = &sdp->sdev_gendev;
+
+ gd->major = sd_major((index & 0xf0) >> 4);
+ gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
+
+ gd->fops = &sd_fops;
+ gd->private_data = &sdkp->driver;
+ gd->queue = sdkp->device->request_queue;
+
+ /* defaults, until the device tells us otherwise */
+ sdp->sector_size = 512;
+ sdkp->capacity = 0;
+ sdkp->media_present = 1;
+ sdkp->write_prot = 0;
+ sdkp->cache_override = 0;
+ sdkp->WCE = 0;
+ sdkp->RCD = 0;
+ sdkp->ATO = 0;
+ sdkp->first_scan = 1;
+ sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS;
+
+ sd_revalidate_disk(gd);
+
+ gd->flags = GENHD_FL_EXT_DEVT;
+ if (sdp->removable) {
+ gd->flags |= GENHD_FL_REMOVABLE;
+ gd->events |= DISK_EVENT_MEDIA_CHANGE;
+ gd->event_flags = DISK_EVENT_FLAG_POLL | DISK_EVENT_FLAG_UEVENT;
+ }
+
+ blk_pm_runtime_init(sdp->request_queue, dev);
+ if (sdp->rpm_autosuspend) {
+ pm_runtime_set_autosuspend_delay(dev,
+ sdp->host->hostt->rpm_autosuspend_delay);
+ }
+ device_add_disk(dev, gd, NULL);
+ if (sdkp->capacity)
+ sd_dif_config_host(sdkp);
+
+ sd_revalidate_disk(gd);
+
+ if (sdkp->security) {
+ sdkp->opal_dev = init_opal_dev(sdkp, &sd_sec_submit);
+ if (sdkp->opal_dev)
+ sd_printk(KERN_NOTICE, sdkp, "supports TCG Opal\n");
+ }
+
+ sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
+ sdp->removable ? "removable " : "");
+ scsi_autopm_put_device(sdp);
+}
+
/**
* sd_probe - called during driver initialization and whenever a
* new scsi device is attached to the system. It is called once
@@ -3455,54 +3517,7 @@ static int sd_probe(struct device *dev)
dev_set_drvdata(dev, sdkp);
- gd->major = sd_major((index & 0xf0) >> 4);
- gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
-
- gd->fops = &sd_fops;
- gd->private_data = &sdkp->driver;
- gd->queue = sdkp->device->request_queue;
-
- /* defaults, until the device tells us otherwise */
- sdp->sector_size = 512;
- sdkp->capacity = 0;
- sdkp->media_present = 1;
- sdkp->write_prot = 0;
- sdkp->cache_override = 0;
- sdkp->WCE = 0;
- sdkp->RCD = 0;
- sdkp->ATO = 0;
- sdkp->first_scan = 1;
- sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS;
-
- sd_revalidate_disk(gd);
-
- gd->flags = GENHD_FL_EXT_DEVT;
- if (sdp->removable) {
- gd->flags |= GENHD_FL_REMOVABLE;
- gd->events |= DISK_EVENT_MEDIA_CHANGE;
- gd->event_flags = DISK_EVENT_FLAG_POLL | DISK_EVENT_FLAG_UEVENT;
- }
-
- blk_pm_runtime_init(sdp->request_queue, dev);
- if (sdp->rpm_autosuspend) {
- pm_runtime_set_autosuspend_delay(dev,
- sdp->host->hostt->rpm_autosuspend_delay);
- }
- device_add_disk(dev, gd, NULL);
- if (sdkp->capacity)
- sd_dif_config_host(sdkp);
-
- sd_revalidate_disk(gd);
-
- if (sdkp->security) {
- sdkp->opal_dev = init_opal_dev(sdkp, &sd_sec_submit);
- if (sdkp->opal_dev)
- sd_printk(KERN_NOTICE, sdkp, "supports TCG Opal\n");
- }
-
- sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
- sdp->removable ? "removable " : "");
- scsi_autopm_put_device(sdp);
+ sd_probe_part2(sdkp);
return 0;
--
2.31.1

View File

@ -0,0 +1,135 @@
From b5dad6e67f9704968ca7d4daf1715667cddafa3d Mon Sep 17 00:00:00 2001
From: Jiping Ma <jiping.ma2@windriver.com>
Date: Wed, 8 Dec 2021 18:34:59 -0800
Subject: [PATCH 2/2] Revert commit f049cf1a7b
commit f049cf1a7b "scsi: sd: Rely on the driver core for asynchronous
probing"
This reverts commit f049cf1a7b6737c75884247c3f6383ef104d255a,
and it is a clean revert, there is not any conflict.
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
---
drivers/scsi/scsi.c | 12 +++++++++---
drivers/scsi/scsi_pm.c | 6 +++++-
drivers/scsi/scsi_priv.h | 1 +
drivers/scsi/sd.c | 12 +++++++++---
4 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 24619c3bebd5..3080292a16cd 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -86,10 +86,15 @@ unsigned int scsi_logging_level;
EXPORT_SYMBOL(scsi_logging_level);
#endif
+/* sd, scsi core and power management need to coordinate flushing async actions */
+ASYNC_DOMAIN(scsi_sd_probe_domain);
+EXPORT_SYMBOL(scsi_sd_probe_domain);
+
/*
- * Domain for asynchronous system resume operations. It is marked 'exclusive'
- * to avoid being included in the async_synchronize_full() that is invoked by
- * dpm_resume().
+ * Separate domain (from scsi_sd_probe_domain) to maximize the benefit of
+ * asynchronous system resume operations. It is marked 'exclusive' to avoid
+ * being included in the async_synchronize_full() that is invoked by
+ * dpm_resume()
*/
ASYNC_DOMAIN_EXCLUSIVE(scsi_sd_pm_domain);
EXPORT_SYMBOL(scsi_sd_pm_domain);
@@ -799,6 +804,7 @@ static void __exit exit_scsi(void)
scsi_exit_devinfo();
scsi_exit_procfs();
scsi_exit_queue();
+ async_unregister_domain(&scsi_sd_probe_domain);
}
subsys_initcall(init_scsi);
diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
index 3717eea37ecb..b3d71b516213 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -175,7 +175,11 @@ static int scsi_bus_resume_common(struct device *dev,
static int scsi_bus_prepare(struct device *dev)
{
- if (scsi_is_host_device(dev)) {
+ if (scsi_is_sdev_device(dev)) {
+ /* sd probing uses async_schedule. Wait until it finishes. */
+ async_synchronize_full_domain(&scsi_sd_probe_domain);
+
+ } else if (scsi_is_host_device(dev)) {
/* Wait until async scanning is finished */
scsi_complete_async_scans();
}
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index 180636d54982..c43456f0870c 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -172,6 +172,7 @@ static inline void scsi_autopm_put_host(struct Scsi_Host *h) {}
#endif /* CONFIG_PM */
extern struct async_domain scsi_sd_pm_domain;
+extern struct async_domain scsi_sd_probe_domain;
/* scsi_dh.c */
#ifdef CONFIG_SCSI_DH
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 2e22ee4501e7..e6c70475f084 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -616,7 +616,6 @@ static struct scsi_driver sd_template = {
.name = "sd",
.owner = THIS_MODULE,
.probe = sd_probe,
- .probe_type = PROBE_PREFER_ASYNCHRONOUS,
.remove = sd_remove,
.shutdown = sd_shutdown,
.pm = &sd_pm_ops,
@@ -3364,8 +3363,12 @@ static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen)
return 0;
}
-static void sd_probe_part2(struct scsi_disk *sdkp)
+/*
+ * The asynchronous part of sd_probe
+ */
+static void sd_probe_async(void *data, async_cookie_t cookie)
{
+ struct scsi_disk *sdkp = data;
struct scsi_device *sdp;
struct gendisk *gd;
u32 index;
@@ -3424,6 +3427,7 @@ static void sd_probe_part2(struct scsi_disk *sdkp)
sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
sdp->removable ? "removable " : "");
scsi_autopm_put_device(sdp);
+ put_device(&sdkp->dev);
}
/**
@@ -3517,7 +3521,8 @@ static int sd_probe(struct device *dev)
dev_set_drvdata(dev, sdkp);
- sd_probe_part2(sdkp);
+ get_device(&sdkp->dev); /* prevent release before async_schedule */
+ async_schedule_domain(sd_probe_async, sdkp, &scsi_sd_probe_domain);
return 0;
@@ -3554,6 +3559,7 @@ static int sd_remove(struct device *dev)
scsi_autopm_get_device(sdkp->device);
async_synchronize_full_domain(&scsi_sd_pm_domain);
+ async_synchronize_full_domain(&scsi_sd_probe_domain);
device_del(&sdkp->dev);
del_gendisk(sdkp->disk);
sd_shutdown(dev);
--
2.31.1

View File

@ -0,0 +1,124 @@
From f53c29e1392a5f67bc937227417bd786e7594e22 Mon Sep 17 00:00:00 2001
From: Thomas Gleixner <tglx@linutronix.de>
Date: Tue, 18 May 2021 11:17:26 +0200
Subject: [PATCH] genirq: Export affinity setter for modules
Perf modules abuse irq_set_affinity_hint() to set the affinity of system
PMU interrupts just because irq_set_affinity() was not exported.
The fact that irq_set_affinity_hint() actually sets the affinity is a
non-documented side effect and the name is clearly saying it's a hint.
To clean this up, export the real affinity setter.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Link: https://lore.kernel.org/r/20210518093117.968251441@linutronix.de
(cherry picked from commit 4d80d6ca5d77fde9880da8466e5b64f250e5bf82)
[mvb: Adjust context for a function that does not exist in v5.10.]
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
include/linux/interrupt.h | 35 ++---------------------------------
kernel/irq/manage.c | 33 ++++++++++++++++++++++++++++++++-
2 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 7545a2f18560..10319f8da486 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -314,39 +314,8 @@ struct irq_affinity_desc {
extern cpumask_var_t irq_default_affinity;
-/* Internal implementation. Use the helpers below */
-extern int __irq_set_affinity(unsigned int irq, const struct cpumask *cpumask,
- bool force);
-
-/**
- * irq_set_affinity - Set the irq affinity of a given irq
- * @irq: Interrupt to set affinity
- * @cpumask: cpumask
- *
- * Fails if cpumask does not contain an online CPU
- */
-static inline int
-irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
-{
- return __irq_set_affinity(irq, cpumask, false);
-}
-
-/**
- * irq_force_affinity - Force the irq affinity of a given irq
- * @irq: Interrupt to set affinity
- * @cpumask: cpumask
- *
- * Same as irq_set_affinity, but without checking the mask against
- * online cpus.
- *
- * Solely for low level cpu hotplug code, where we need to make per
- * cpu interrupts affine before the cpu becomes online.
- */
-static inline int
-irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
-{
- return __irq_set_affinity(irq, cpumask, true);
-}
+extern int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask);
+extern int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask);
extern int irq_can_set_affinity(unsigned int irq);
extern int irq_select_affinity(unsigned int irq);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 84a120d3abef..d7974de65659 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -371,7 +371,8 @@ int irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask,
return ret;
}
-int __irq_set_affinity(unsigned int irq, const struct cpumask *mask, bool force)
+static int __irq_set_affinity(unsigned int irq, const struct cpumask *mask,
+ bool force)
{
struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
@@ -386,6 +387,36 @@ int __irq_set_affinity(unsigned int irq, const struct cpumask *mask, bool force)
return ret;
}
+/**
+ * irq_set_affinity - Set the irq affinity of a given irq
+ * @irq: Interrupt to set affinity
+ * @cpumask: cpumask
+ *
+ * Fails if cpumask does not contain an online CPU
+ */
+int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+{
+ return __irq_set_affinity(irq, cpumask, false);
+}
+EXPORT_SYMBOL_GPL(irq_set_affinity);
+
+/**
+ * irq_force_affinity - Force the irq affinity of a given irq
+ * @irq: Interrupt to set affinity
+ * @cpumask: cpumask
+ *
+ * Same as irq_set_affinity, but without checking the mask against
+ * online cpus.
+ *
+ * Solely for low level cpu hotplug code, where we need to make per
+ * cpu interrupts affine before the cpu becomes online.
+ */
+int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
+{
+ return __irq_set_affinity(irq, cpumask, true);
+}
+EXPORT_SYMBOL_GPL(irq_force_affinity);
+
int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
{
unsigned long flags;
--
2.29.2

View File

@ -0,0 +1,146 @@
From 65d6ca9e8f41d14239e3e7618126f65df9982f92 Mon Sep 17 00:00:00 2001
From: Thomas Gleixner <tglx@linutronix.de>
Date: Fri, 3 Sep 2021 11:24:17 -0400
Subject: [PATCH] genirq: Provide new interfaces for affinity hints
The discussion about removing the side effect of irq_set_affinity_hint() of
actually applying the cpumask (if not NULL) as affinity to the interrupt,
unearthed a few unpleasantries:
1) The modular perf drivers rely on the current behaviour for the very
wrong reasons.
2) While none of the other drivers prevents user space from changing
the affinity, a cursorily inspection shows that there are at least
expectations in some drivers.
#1 needs to be cleaned up anyway, so that's not a problem
#2 might result in subtle regressions especially when irqbalanced (which
nowadays ignores the affinity hint) is disabled.
Provide new interfaces:
irq_update_affinity_hint() - Only sets the affinity hint pointer
irq_set_affinity_and_hint() - Set the pointer and apply the affinity to
the interrupt
Make irq_set_affinity_hint() a wrapper around irq_apply_affinity_hint() and
document it to be phased out.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Nitesh Narayan Lal <nitesh@redhat.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20210501021832.743094-1-jesse.brandeburg@intel.com
Link: https://lore.kernel.org/r/20210903152430.244937-2-nitesh@redhat.com
(cherry picked from commit 65c7cdedeb3026fabcc967a7aae2f755ad4d0783)
[mvb: Adapt to v5.10 by resolving a minor merge conflict.]
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
include/linux/interrupt.h | 52 ++++++++++++++++++++++++++++++++++++++-
kernel/irq/manage.c | 8 +++---
2 files changed, 55 insertions(+), 5 deletions(-)
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 10319f8da486..c1520fa7e843 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -320,7 +320,45 @@ extern int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask);
extern int irq_can_set_affinity(unsigned int irq);
extern int irq_select_affinity(unsigned int irq);
-extern int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m);
+extern int __irq_apply_affinity_hint(unsigned int irq, const struct cpumask *m,
+ bool setaffinity);
+
+/**
+ * irq_update_affinity_hint - Update the affinity hint
+ * @irq: Interrupt to update
+ * @m: cpumask pointer (NULL to clear the hint)
+ *
+ * Updates the affinity hint, but does not change the affinity of the interrupt.
+ */
+static inline int
+irq_update_affinity_hint(unsigned int irq, const struct cpumask *m)
+{
+ return __irq_apply_affinity_hint(irq, m, false);
+}
+
+/**
+ * irq_set_affinity_and_hint - Update the affinity hint and apply the provided
+ * cpumask to the interrupt
+ * @irq: Interrupt to update
+ * @m: cpumask pointer (NULL to clear the hint)
+ *
+ * Updates the affinity hint and if @m is not NULL it applies it as the
+ * affinity of that interrupt.
+ */
+static inline int
+irq_set_affinity_and_hint(unsigned int irq, const struct cpumask *m)
+{
+ return __irq_apply_affinity_hint(irq, m, true);
+}
+
+/*
+ * Deprecated. Use irq_update_affinity_hint() or irq_set_affinity_and_hint()
+ * instead.
+ */
+static inline int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
+{
+ return irq_set_affinity_and_hint(irq, m);
+}
extern int
irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify);
@@ -350,6 +388,18 @@ static inline int irq_can_set_affinity(unsigned int irq)
static inline int irq_select_affinity(unsigned int irq) { return 0; }
+static inline int irq_update_affinity_hint(unsigned int irq,
+ const struct cpumask *m)
+{
+ return -EINVAL;
+}
+
+static inline int irq_set_affinity_and_hint(unsigned int irq,
+ const struct cpumask *m)
+{
+ return -EINVAL;
+}
+
static inline int irq_set_affinity_hint(unsigned int irq,
const struct cpumask *m)
{
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index d7974de65659..836e7111b584 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -417,7 +417,8 @@ int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
}
EXPORT_SYMBOL_GPL(irq_force_affinity);
-int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
+int __irq_apply_affinity_hint(unsigned int irq, const struct cpumask *m,
+ bool setaffinity)
{
unsigned long flags;
struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
@@ -426,12 +427,11 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
return -EINVAL;
desc->affinity_hint = m;
irq_put_desc_unlock(desc, flags);
- /* set the initial affinity to prevent every interrupt being on CPU0 */
- if (m)
+ if (m && setaffinity)
__irq_set_affinity(irq, m, false);
return 0;
}
-EXPORT_SYMBOL_GPL(irq_set_affinity_hint);
+EXPORT_SYMBOL_GPL(__irq_apply_affinity_hint);
static void irq_affinity_notify(struct work_struct *work)
{
--
2.29.2

View File

@ -0,0 +1,64 @@
From ec3682a03a0be93ec7e6c8706ab89846cfad4232 Mon Sep 17 00:00:00 2001
From: Nitesh Narayan Lal <nitesh@redhat.com>
Date: Fri, 3 Sep 2021 11:24:25 -0400
Subject: [PATCH] ixgbe: Use irq_update_affinity_hint()
The driver uses irq_set_affinity_hint() to update the affinity_hint mask
that is consumed by the userspace to distribute the interrupts. However,
under the hood irq_set_affinity_hint() also applies the provided cpumask
(if not NULL) as the affinity for the given interrupt which is an
undocumented side effect.
To remove this side effect irq_set_affinity_hint() has been marked
as deprecated and new interfaces have been introduced. Hence, replace the
irq_set_affinity_hint() with the new interface irq_update_affinity_hint()
that only updates the affinity_hint pointer.
Signed-off-by: Nitesh Narayan Lal <nitesh@redhat.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Link: https://lore.kernel.org/r/20210903152430.244937-10-nitesh@redhat.com
(cherry picked from commit cc493264c01d055742a34cfbaecaffb258dcc58c)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index ffe322136c58..fe10776d8479 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3250,8 +3250,8 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
/* If Flow Director is enabled, set interrupt affinity */
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) {
/* assign the mask for this irq */
- irq_set_affinity_hint(entry->vector,
- &q_vector->affinity_mask);
+ irq_update_affinity_hint(entry->vector,
+ &q_vector->affinity_mask);
}
}
@@ -3267,8 +3267,8 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
free_queue_irqs:
while (vector) {
vector--;
- irq_set_affinity_hint(adapter->msix_entries[vector].vector,
- NULL);
+ irq_update_affinity_hint(adapter->msix_entries[vector].vector,
+ NULL);
free_irq(adapter->msix_entries[vector].vector,
adapter->q_vector[vector]);
}
@@ -3401,7 +3401,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
continue;
/* clear the affinity_mask in the IRQ descriptor */
- irq_set_affinity_hint(entry->vector, NULL);
+ irq_update_affinity_hint(entry->vector, NULL);
free_irq(entry->vector, q_vector);
}
--
2.29.2

View File

@ -0,0 +1,743 @@
From f7fadaaf14372fcc39555b1e3a1a0efa62472dfd Mon Sep 17 00:00:00 2001
From: Dave Ertman <david.m.ertman@intel.com>
Date: Wed, 2 Dec 2020 16:54:24 -0800
Subject: [PATCH] Add auxiliary bus support
Add support for the Auxiliary Bus, auxiliary_device and auxiliary_driver.
It enables drivers to create an auxiliary_device and bind an
auxiliary_driver to it.
The bus supports probe/remove shutdown and suspend/resume callbacks.
Each auxiliary_device has a unique string based id; driver binds to
an auxiliary_device based on this id through the bus.
Co-developed-by: Kiran Patil <kiran.patil@intel.com>
Co-developed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Co-developed-by: Fred Oh <fred.oh@linux.intel.com>
Co-developed-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Kiran Patil <kiran.patil@intel.com>
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Fred Oh <fred.oh@linux.intel.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Dave Ertman <david.m.ertman@intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Shiraz Saleem <shiraz.saleem@intel.com>
Reviewed-by: Parav Pandit <parav@mellanox.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Martin Habets <mhabets@solarflare.com>
Link: https://lore.kernel.org/r/20201113161859.1775473-2-david.m.ertman@intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Link: https://lore.kernel.org/r/160695681289.505290.8978295443574440604.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 7de3697e9cbd4bd3d62bafa249d57990e1b8f294)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
Documentation/driver-api/auxiliary_bus.rst | 234 ++++++++++++++++++
Documentation/driver-api/index.rst | 1 +
drivers/base/Kconfig | 3 +
drivers/base/Makefile | 1 +
drivers/base/auxiliary.c | 268 +++++++++++++++++++++
include/linux/auxiliary_bus.h | 78 ++++++
include/linux/mod_devicetable.h | 8 +
scripts/mod/devicetable-offsets.c | 3 +
scripts/mod/file2alias.c | 8 +
9 files changed, 604 insertions(+)
create mode 100644 Documentation/driver-api/auxiliary_bus.rst
create mode 100644 drivers/base/auxiliary.c
create mode 100644 include/linux/auxiliary_bus.h
diff --git a/Documentation/driver-api/auxiliary_bus.rst b/Documentation/driver-api/auxiliary_bus.rst
new file mode 100644
index 000000000000..5dd7804631ef
--- /dev/null
+++ b/Documentation/driver-api/auxiliary_bus.rst
@@ -0,0 +1,234 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+=============
+Auxiliary Bus
+=============
+
+In some subsystems, the functionality of the core device (PCI/ACPI/other) is
+too complex for a single device to be managed by a monolithic driver
+(e.g. Sound Open Firmware), multiple devices might implement a common
+intersection of functionality (e.g. NICs + RDMA), or a driver may want to
+export an interface for another subsystem to drive (e.g. SIOV Physical Function
+export Virtual Function management). A split of the functinoality into child-
+devices representing sub-domains of functionality makes it possible to
+compartmentalize, layer, and distribute domain-specific concerns via a Linux
+device-driver model.
+
+An example for this kind of requirement is the audio subsystem where a single
+IP is handling multiple entities such as HDMI, Soundwire, local devices such as
+mics/speakers etc. The split for the core's functionality can be arbitrary or
+be defined by the DSP firmware topology and include hooks for test/debug. This
+allows for the audio core device to be minimal and focused on hardware-specific
+control and communication.
+
+Each auxiliary_device represents a part of its parent functionality. The
+generic behavior can be extended and specialized as needed by encapsulating an
+auxiliary_device within other domain-specific structures and the use of .ops
+callbacks. Devices on the auxiliary bus do not share any structures and the use
+of a communication channel with the parent is domain-specific.
+
+Note that ops are intended as a way to augment instance behavior within a class
+of auxiliary devices, it is not the mechanism for exporting common
+infrastructure from the parent. Consider EXPORT_SYMBOL_NS() to convey
+infrastructure from the parent module to the auxiliary module(s).
+
+
+When Should the Auxiliary Bus Be Used
+=====================================
+
+The auxiliary bus is to be used when a driver and one or more kernel modules,
+who share a common header file with the driver, need a mechanism to connect and
+provide access to a shared object allocated by the auxiliary_device's
+registering driver. The registering driver for the auxiliary_device(s) and the
+kernel module(s) registering auxiliary_drivers can be from the same subsystem,
+or from multiple subsystems.
+
+The emphasis here is on a common generic interface that keeps subsystem
+customization out of the bus infrastructure.
+
+One example is a PCI network device that is RDMA-capable and exports a child
+device to be driven by an auxiliary_driver in the RDMA subsystem. The PCI
+driver allocates and registers an auxiliary_device for each physical
+function on the NIC. The RDMA driver registers an auxiliary_driver that claims
+each of these auxiliary_devices. This conveys data/ops published by the parent
+PCI device/driver to the RDMA auxiliary_driver.
+
+Another use case is for the PCI device to be split out into multiple sub
+functions. For each sub function an auxiliary_device is created. A PCI sub
+function driver binds to such devices that creates its own one or more class
+devices. A PCI sub function auxiliary device is likely to be contained in a
+struct with additional attributes such as user defined sub function number and
+optional attributes such as resources and a link to the parent device. These
+attributes could be used by systemd/udev; and hence should be initialized
+before a driver binds to an auxiliary_device.
+
+A key requirement for utilizing the auxiliary bus is that there is no
+dependency on a physical bus, device, register accesses or regmap support.
+These individual devices split from the core cannot live on the platform bus as
+they are not physical devices that are controlled by DT/ACPI. The same
+argument applies for not using MFD in this scenario as MFD relies on individual
+function devices being physical devices.
+
+Auxiliary Device
+================
+
+An auxiliary_device represents a part of its parent device's functionality. It
+is given a name that, combined with the registering drivers KBUILD_MODNAME,
+creates a match_name that is used for driver binding, and an id that combined
+with the match_name provide a unique name to register with the bus subsystem.
+
+Registering an auxiliary_device is a two-step process. First call
+auxiliary_device_init(), which checks several aspects of the auxiliary_device
+struct and performs a device_initialize(). After this step completes, any
+error state must have a call to auxiliary_device_uninit() in its resolution path.
+The second step in registering an auxiliary_device is to perform a call to
+auxiliary_device_add(), which sets the name of the device and add the device to
+the bus.
+
+Unregistering an auxiliary_device is also a two-step process to mirror the
+register process. First call auxiliary_device_delete(), then call
+auxiliary_device_uninit().
+
+.. code-block:: c
+
+ struct auxiliary_device {
+ struct device dev;
+ const char *name;
+ u32 id;
+ };
+
+If two auxiliary_devices both with a match_name "mod.foo" are registered onto
+the bus, they must have unique id values (e.g. "x" and "y") so that the
+registered devices names are "mod.foo.x" and "mod.foo.y". If match_name + id
+are not unique, then the device_add fails and generates an error message.
+
+The auxiliary_device.dev.type.release or auxiliary_device.dev.release must be
+populated with a non-NULL pointer to successfully register the auxiliary_device.
+
+The auxiliary_device.dev.parent must also be populated.
+
+Auxiliary Device Memory Model and Lifespan
+------------------------------------------
+
+The registering driver is the entity that allocates memory for the
+auxiliary_device and register it on the auxiliary bus. It is important to note
+that, as opposed to the platform bus, the registering driver is wholly
+responsible for the management for the memory used for the driver object.
+
+A parent object, defined in the shared header file, contains the
+auxiliary_device. It also contains a pointer to the shared object(s), which
+also is defined in the shared header. Both the parent object and the shared
+object(s) are allocated by the registering driver. This layout allows the
+auxiliary_driver's registering module to perform a container_of() call to go
+from the pointer to the auxiliary_device, that is passed during the call to the
+auxiliary_driver's probe function, up to the parent object, and then have
+access to the shared object(s).
+
+The memory for the auxiliary_device is freed only in its release() callback
+flow as defined by its registering driver.
+
+The memory for the shared object(s) must have a lifespan equal to, or greater
+than, the lifespan of the memory for the auxiliary_device. The auxiliary_driver
+should only consider that this shared object is valid as long as the
+auxiliary_device is still registered on the auxiliary bus. It is up to the
+registering driver to manage (e.g. free or keep available) the memory for the
+shared object beyond the life of the auxiliary_device.
+
+The registering driver must unregister all auxiliary devices before its own
+driver.remove() is completed.
+
+Auxiliary Drivers
+=================
+
+Auxiliary drivers follow the standard driver model convention, where
+discovery/enumeration is handled by the core, and drivers
+provide probe() and remove() methods. They support power management
+and shutdown notifications using the standard conventions.
+
+.. code-block:: c
+
+ struct auxiliary_driver {
+ int (*probe)(struct auxiliary_device *,
+ const struct auxiliary_device_id *id);
+ int (*remove)(struct auxiliary_device *);
+ void (*shutdown)(struct auxiliary_device *);
+ int (*suspend)(struct auxiliary_device *, pm_message_t);
+ int (*resume)(struct auxiliary_device *);
+ struct device_driver driver;
+ const struct auxiliary_device_id *id_table;
+ };
+
+Auxiliary drivers register themselves with the bus by calling
+auxiliary_driver_register(). The id_table contains the match_names of auxiliary
+devices that a driver can bind with.
+
+Example Usage
+=============
+
+Auxiliary devices are created and registered by a subsystem-level core device
+that needs to break up its functionality into smaller fragments. One way to
+extend the scope of an auxiliary_device is to encapsulate it within a domain-
+pecific structure defined by the parent device. This structure contains the
+auxiliary_device and any associated shared data/callbacks needed to establish
+the connection with the parent.
+
+An example is:
+
+.. code-block:: c
+
+ struct foo {
+ struct auxiliary_device auxdev;
+ void (*connect)(struct auxiliary_device *auxdev);
+ void (*disconnect)(struct auxiliary_device *auxdev);
+ void *data;
+ };
+
+The parent device then registers the auxiliary_device by calling
+auxiliary_device_init(), and then auxiliary_device_add(), with the pointer to
+the auxdev member of the above structure. The parent provides a name for the
+auxiliary_device that, combined with the parent's KBUILD_MODNAME, creates a
+match_name that is be used for matching and binding with a driver.
+
+Whenever an auxiliary_driver is registered, based on the match_name, the
+auxiliary_driver's probe() is invoked for the matching devices. The
+auxiliary_driver can also be encapsulated inside custom drivers that make the
+core device's functionality extensible by adding additional domain-specific ops
+as follows:
+
+.. code-block:: c
+
+ struct my_ops {
+ void (*send)(struct auxiliary_device *auxdev);
+ void (*receive)(struct auxiliary_device *auxdev);
+ };
+
+
+ struct my_driver {
+ struct auxiliary_driver auxiliary_drv;
+ const struct my_ops ops;
+ };
+
+An example of this type of usage is:
+
+.. code-block:: c
+
+ const struct auxiliary_device_id my_auxiliary_id_table[] = {
+ { .name = "foo_mod.foo_dev" },
+ { },
+ };
+
+ const struct my_ops my_custom_ops = {
+ .send = my_tx,
+ .receive = my_rx,
+ };
+
+ const struct my_driver my_drv = {
+ .auxiliary_drv = {
+ .name = "myauxiliarydrv",
+ .id_table = my_auxiliary_id_table,
+ .probe = my_probe,
+ .remove = my_remove,
+ .shutdown = my_shutdown,
+ },
+ .ops = my_custom_ops,
+ };
diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
index f357f3eb400c..86759a74b7f1 100644
--- a/Documentation/driver-api/index.rst
+++ b/Documentation/driver-api/index.rst
@@ -72,6 +72,7 @@ available subsections can be seen below.
thermal/index
fpga/index
acpi/index
+ auxiliary_bus
backlight/lp855x-driver.rst
connector
console
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 8d7001712062..040be48ce046 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -1,6 +1,9 @@
# SPDX-License-Identifier: GPL-2.0
menu "Generic Driver Options"
+config AUXILIARY_BUS
+ bool
+
config UEVENT_HELPER
bool "Support for uevent helper"
help
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 41369fc7004f..5e7bf9669a81 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -7,6 +7,7 @@ obj-y := component.o core.o bus.o dd.o syscore.o \
attribute_container.o transport_class.o \
topology.o container.o property.o cacheinfo.o \
swnode.o
+obj-$(CONFIG_AUXILIARY_BUS) += auxiliary.o
obj-$(CONFIG_DEVTMPFS) += devtmpfs.o
obj-y += power/
obj-$(CONFIG_ISA_BUS_API) += isa.o
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
new file mode 100644
index 000000000000..ef2af417438b
--- /dev/null
+++ b/drivers/base/auxiliary.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2019-2020 Intel Corporation
+ *
+ * Please see Documentation/driver-api/auxiliary_bus.rst for more information.
+ */
+
+#define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
+#include <linux/string.h>
+#include <linux/auxiliary_bus.h>
+
+static const struct auxiliary_device_id *auxiliary_match_id(const struct auxiliary_device_id *id,
+ const struct auxiliary_device *auxdev)
+{
+ for (; id->name[0]; id++) {
+ const char *p = strrchr(dev_name(&auxdev->dev), '.');
+ int match_size;
+
+ if (!p)
+ continue;
+ match_size = p - dev_name(&auxdev->dev);
+
+ /* use dev_name(&auxdev->dev) prefix before last '.' char to match to */
+ if (strlen(id->name) == match_size &&
+ !strncmp(dev_name(&auxdev->dev), id->name, match_size))
+ return id;
+ }
+ return NULL;
+}
+
+static int auxiliary_match(struct device *dev, struct device_driver *drv)
+{
+ struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
+ struct auxiliary_driver *auxdrv = to_auxiliary_drv(drv);
+
+ return !!auxiliary_match_id(auxdrv->id_table, auxdev);
+}
+
+static int auxiliary_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ const char *name, *p;
+
+ name = dev_name(dev);
+ p = strrchr(name, '.');
+
+ return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX, (int)(p - name),
+ name);
+}
+
+static const struct dev_pm_ops auxiliary_dev_pm_ops = {
+ SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_generic_suspend, pm_generic_resume)
+};
+
+static int auxiliary_bus_probe(struct device *dev)
+{
+ struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);
+ struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
+ int ret;
+
+ ret = dev_pm_domain_attach(dev, true);
+ if (ret) {
+ dev_warn(dev, "Failed to attach to PM Domain : %d\n", ret);
+ return ret;
+ }
+
+ ret = auxdrv->probe(auxdev, auxiliary_match_id(auxdrv->id_table, auxdev));
+ if (ret)
+ dev_pm_domain_detach(dev, true);
+
+ return ret;
+}
+
+static int auxiliary_bus_remove(struct device *dev)
+{
+ struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);
+ struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
+ int ret = 0;
+
+ if (auxdrv->remove)
+ ret = auxdrv->remove(auxdev);
+ dev_pm_domain_detach(dev, true);
+
+ return ret;
+}
+
+static void auxiliary_bus_shutdown(struct device *dev)
+{
+ struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);
+ struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
+
+ if (auxdrv->shutdown)
+ auxdrv->shutdown(auxdev);
+}
+
+static struct bus_type auxiliary_bus_type = {
+ .name = "auxiliary",
+ .probe = auxiliary_bus_probe,
+ .remove = auxiliary_bus_remove,
+ .shutdown = auxiliary_bus_shutdown,
+ .match = auxiliary_match,
+ .uevent = auxiliary_uevent,
+ .pm = &auxiliary_dev_pm_ops,
+};
+
+/**
+ * auxiliary_device_init - check auxiliary_device and initialize
+ * @auxdev: auxiliary device struct
+ *
+ * This is the first step in the two-step process to register an auxiliary_device.
+ *
+ * When this function returns an error code, then the device_initialize will *not* have
+ * been performed, and the caller will be responsible to free any memory allocated for the
+ * auxiliary_device in the error path directly.
+ *
+ * It returns 0 on success. On success, the device_initialize has been performed. After this
+ * point any error unwinding will need to include a call to auxiliary_device_uninit().
+ * In this post-initialize error scenario, a call to the device's .release callback will be
+ * triggered, and all memory clean-up is expected to be handled there.
+ */
+int auxiliary_device_init(struct auxiliary_device *auxdev)
+{
+ struct device *dev = &auxdev->dev;
+
+ if (!dev->parent) {
+ pr_err("auxiliary_device has a NULL dev->parent\n");
+ return -EINVAL;
+ }
+
+ if (!auxdev->name) {
+ pr_err("auxiliary_device has a NULL name\n");
+ return -EINVAL;
+ }
+
+ dev->bus = &auxiliary_bus_type;
+ device_initialize(&auxdev->dev);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(auxiliary_device_init);
+
+/**
+ * __auxiliary_device_add - add an auxiliary bus device
+ * @auxdev: auxiliary bus device to add to the bus
+ * @modname: name of the parent device's driver module
+ *
+ * This is the second step in the two-step process to register an auxiliary_device.
+ *
+ * This function must be called after a successful call to auxiliary_device_init(), which
+ * will perform the device_initialize. This means that if this returns an error code, then a
+ * call to auxiliary_device_uninit() must be performed so that the .release callback will
+ * be triggered to free the memory associated with the auxiliary_device.
+ *
+ * The expectation is that users will call the "auxiliary_device_add" macro so that the caller's
+ * KBUILD_MODNAME is automatically inserted for the modname parameter. Only if a user requires
+ * a custom name would this version be called directly.
+ */
+int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname)
+{
+ struct device *dev = &auxdev->dev;
+ int ret;
+
+ if (!modname) {
+ pr_err("auxiliary device modname is NULL\n");
+ return -EINVAL;
+ }
+
+ ret = dev_set_name(dev, "%s.%s.%d", modname, auxdev->name, auxdev->id);
+ if (ret) {
+ pr_err("auxiliary device dev_set_name failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = device_add(dev);
+ if (ret)
+ dev_err(dev, "adding auxiliary device failed!: %d\n", ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__auxiliary_device_add);
+
+/**
+ * auxiliary_find_device - auxiliary device iterator for locating a particular device.
+ * @start: Device to begin with
+ * @data: Data to pass to match function
+ * @match: Callback function to check device
+ *
+ * This function returns a reference to a device that is 'found'
+ * for later use, as determined by the @match callback.
+ *
+ * The callback should return 0 if the device doesn't match and non-zero
+ * if it does. If the callback returns non-zero, this function will
+ * return to the caller and not iterate over any more devices.
+ */
+struct auxiliary_device *
+auxiliary_find_device(struct device *start, const void *data,
+ int (*match)(struct device *dev, const void *data))
+{
+ struct device *dev;
+
+ dev = bus_find_device(&auxiliary_bus_type, start, data, match);
+ if (!dev)
+ return NULL;
+
+ return to_auxiliary_dev(dev);
+}
+EXPORT_SYMBOL_GPL(auxiliary_find_device);
+
+/**
+ * __auxiliary_driver_register - register a driver for auxiliary bus devices
+ * @auxdrv: auxiliary_driver structure
+ * @owner: owning module/driver
+ * @modname: KBUILD_MODNAME for parent driver
+ */
+int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner,
+ const char *modname)
+{
+ if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table))
+ return -EINVAL;
+
+ if (auxdrv->name)
+ auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname, auxdrv->name);
+ else
+ auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s", modname);
+ if (!auxdrv->driver.name)
+ return -ENOMEM;
+
+ auxdrv->driver.owner = owner;
+ auxdrv->driver.bus = &auxiliary_bus_type;
+ auxdrv->driver.mod_name = modname;
+
+ return driver_register(&auxdrv->driver);
+}
+EXPORT_SYMBOL_GPL(__auxiliary_driver_register);
+
+/**
+ * auxiliary_driver_unregister - unregister a driver
+ * @auxdrv: auxiliary_driver structure
+ */
+void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv)
+{
+ driver_unregister(&auxdrv->driver);
+ kfree(auxdrv->driver.name);
+}
+EXPORT_SYMBOL_GPL(auxiliary_driver_unregister);
+
+static int __init auxiliary_bus_init(void)
+{
+ return bus_register(&auxiliary_bus_type);
+}
+
+static void __exit auxiliary_bus_exit(void)
+{
+ bus_unregister(&auxiliary_bus_type);
+}
+
+module_init(auxiliary_bus_init);
+module_exit(auxiliary_bus_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Auxiliary Bus");
+MODULE_AUTHOR("David Ertman <david.m.ertman@intel.com>");
+MODULE_AUTHOR("Kiran Patil <kiran.patil@intel.com>");
diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h
new file mode 100644
index 000000000000..282fbf7bf9af
--- /dev/null
+++ b/include/linux/auxiliary_bus.h
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2020 Intel Corporation
+ *
+ * Please see Documentation/driver-api/auxiliary_bus.rst for more information.
+ */
+
+#ifndef _AUXILIARY_BUS_H_
+#define _AUXILIARY_BUS_H_
+
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+
+struct auxiliary_device {
+ struct device dev;
+ const char *name;
+ u32 id;
+};
+
+struct auxiliary_driver {
+ int (*probe)(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id);
+ int (*remove)(struct auxiliary_device *auxdev);
+ void (*shutdown)(struct auxiliary_device *auxdev);
+ int (*suspend)(struct auxiliary_device *auxdev, pm_message_t state);
+ int (*resume)(struct auxiliary_device *auxdev);
+ const char *name;
+ struct device_driver driver;
+ const struct auxiliary_device_id *id_table;
+};
+
+static inline struct auxiliary_device *to_auxiliary_dev(struct device *dev)
+{
+ return container_of(dev, struct auxiliary_device, dev);
+}
+
+static inline struct auxiliary_driver *to_auxiliary_drv(struct device_driver *drv)
+{
+ return container_of(drv, struct auxiliary_driver, driver);
+}
+
+int auxiliary_device_init(struct auxiliary_device *auxdev);
+int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname);
+#define auxiliary_device_add(auxdev) __auxiliary_device_add(auxdev, KBUILD_MODNAME)
+
+static inline void auxiliary_device_uninit(struct auxiliary_device *auxdev)
+{
+ put_device(&auxdev->dev);
+}
+
+static inline void auxiliary_device_delete(struct auxiliary_device *auxdev)
+{
+ device_del(&auxdev->dev);
+}
+
+int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner,
+ const char *modname);
+#define auxiliary_driver_register(auxdrv) \
+ __auxiliary_driver_register(auxdrv, THIS_MODULE, KBUILD_MODNAME)
+
+void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv);
+
+/**
+ * module_auxiliary_driver() - Helper macro for registering an auxiliary driver
+ * @__auxiliary_driver: auxiliary driver struct
+ *
+ * Helper macro for auxiliary drivers which do not do anything special in
+ * module init/exit. This eliminates a lot of boilerplate. Each module may only
+ * use this macro once, and calling it replaces module_init() and module_exit()
+ */
+#define module_auxiliary_driver(__auxiliary_driver) \
+ module_driver(__auxiliary_driver, auxiliary_driver_register, auxiliary_driver_unregister)
+
+struct auxiliary_device *
+auxiliary_find_device(struct device *start, const void *data,
+ int (*match)(struct device *dev, const void *data));
+
+#endif /* _AUXILIARY_BUS_H_ */
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 5b08a473cdba..c425290b21e2 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -838,4 +838,12 @@ struct mhi_device_id {
kernel_ulong_t driver_data;
};
+#define AUXILIARY_NAME_SIZE 32
+#define AUXILIARY_MODULE_PREFIX "auxiliary:"
+
+struct auxiliary_device_id {
+ char name[AUXILIARY_NAME_SIZE];
+ kernel_ulong_t driver_data;
+};
+
#endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index 27007c18e754..e377f52dbfa3 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -243,5 +243,8 @@ int main(void)
DEVID(mhi_device_id);
DEVID_FIELD(mhi_device_id, chan);
+ DEVID(auxiliary_device_id);
+ DEVID_FIELD(auxiliary_device_id, name);
+
return 0;
}
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 2417dd1dee33..fb4827027536 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1364,6 +1364,13 @@ static int do_mhi_entry(const char *filename, void *symval, char *alias)
{
DEF_FIELD_ADDR(symval, mhi_device_id, chan);
sprintf(alias, MHI_DEVICE_MODALIAS_FMT, *chan);
+ return 1;
+}
+
+static int do_auxiliary_entry(const char *filename, void *symval, char *alias)
+{
+ DEF_FIELD_ADDR(symval, auxiliary_device_id, name);
+ sprintf(alias, AUXILIARY_MODULE_PREFIX "%s", *name);
return 1;
}
@@ -1442,6 +1449,7 @@ static const struct devtable devtable[] = {
{"tee", SIZE_tee_client_device_id, do_tee_entry},
{"wmi", SIZE_wmi_device_id, do_wmi_entry},
{"mhi", SIZE_mhi_device_id, do_mhi_entry},
+ {"auxiliary", SIZE_auxiliary_device_id, do_auxiliary_entry},
};
/* Create MODULE_ALIAS() statements.
--
2.29.2

View File

@ -0,0 +1,54 @@
From e691ecf482fc75f7ed09aac3fa58436b56d5393b Mon Sep 17 00:00:00 2001
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: Fri, 4 Dec 2020 12:43:47 +0100
Subject: [PATCH] driver core: auxiliary bus: move slab.h from include file
No need to include slab.h in include/linux/auxiliary_bus.h, as it is not
needed there. Move it to drivers/base/auxiliary.c instead.
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Ertman <david.m.ertman@intel.com>
Cc: Fred Oh <fred.oh@linux.intel.com>
Cc: Kiran Patil <kiran.patil@intel.com>
Cc: Leon Romanovsky <leonro@nvidia.com>
Cc: Martin Habets <mhabets@solarflare.com>
Cc: Parav Pandit <parav@mellanox.com>
Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Cc: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Cc: Shiraz Saleem <shiraz.saleem@intel.com>
Link: https://lore.kernel.org/r/X8og8xi3WkoYXet9@kroah.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 7bbb79ff5f7499e0c5d65987458410e8099207d8)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/base/auxiliary.c | 1 +
include/linux/auxiliary_bus.h | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index ef2af417438b..eca36d6284d0 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -9,6 +9,7 @@
#include <linux/device.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h
index 282fbf7bf9af..3580743d0e8d 100644
--- a/include/linux/auxiliary_bus.h
+++ b/include/linux/auxiliary_bus.h
@@ -10,7 +10,6 @@
#include <linux/device.h>
#include <linux/mod_devicetable.h>
-#include <linux/slab.h>
struct auxiliary_device {
struct device dev;
--
2.29.2

View File

@ -0,0 +1,79 @@
From 3dd9d97b9329c10548b0376307bdda8e23310fa9 Mon Sep 17 00:00:00 2001
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: Fri, 4 Dec 2020 12:44:07 +0100
Subject: [PATCH] driver core: auxiliary bus: make remove function return void
There's an effort to move the remove() callback in the driver core to
not return an int, as nothing can be done if this function fails. To
make that effort easier, make the aux bus remove function void to start
with so that no users have to be changed sometime in the future.
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Ertman <david.m.ertman@intel.com>
Cc: Fred Oh <fred.oh@linux.intel.com>
Cc: Kiran Patil <kiran.patil@intel.com>
Cc: Leon Romanovsky <leonro@nvidia.com>
Cc: Martin Habets <mhabets@solarflare.com>
Cc: Parav Pandit <parav@mellanox.com>
Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Cc: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Cc: Shiraz Saleem <shiraz.saleem@intel.com>
Link: https://lore.kernel.org/r/X8ohB1ks1NK7kPop@kroah.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 8142a46c50d2dd8160c42284e1044eed3bec0d18)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
Documentation/driver-api/auxiliary_bus.rst | 2 +-
drivers/base/auxiliary.c | 5 ++---
include/linux/auxiliary_bus.h | 2 +-
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/Documentation/driver-api/auxiliary_bus.rst b/Documentation/driver-api/auxiliary_bus.rst
index 5dd7804631ef..2312506b0674 100644
--- a/Documentation/driver-api/auxiliary_bus.rst
+++ b/Documentation/driver-api/auxiliary_bus.rst
@@ -150,7 +150,7 @@ and shutdown notifications using the standard conventions.
struct auxiliary_driver {
int (*probe)(struct auxiliary_device *,
const struct auxiliary_device_id *id);
- int (*remove)(struct auxiliary_device *);
+ void (*remove)(struct auxiliary_device *);
void (*shutdown)(struct auxiliary_device *);
int (*suspend)(struct auxiliary_device *, pm_message_t);
int (*resume)(struct auxiliary_device *);
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index eca36d6284d0..c44e85802b43 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -82,13 +82,12 @@ static int auxiliary_bus_remove(struct device *dev)
{
struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);
struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
- int ret = 0;
if (auxdrv->remove)
- ret = auxdrv->remove(auxdev);
+ auxdrv->remove(auxdev);
dev_pm_domain_detach(dev, true);
- return ret;
+ return 0;
}
static void auxiliary_bus_shutdown(struct device *dev)
diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h
index 3580743d0e8d..d67b17606210 100644
--- a/include/linux/auxiliary_bus.h
+++ b/include/linux/auxiliary_bus.h
@@ -19,7 +19,7 @@ struct auxiliary_device {
struct auxiliary_driver {
int (*probe)(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id);
- int (*remove)(struct auxiliary_device *auxdev);
+ void (*remove)(struct auxiliary_device *auxdev);
void (*shutdown)(struct auxiliary_device *auxdev);
int (*suspend)(struct auxiliary_device *auxdev, pm_message_t state);
int (*resume)(struct auxiliary_device *auxdev);
--
2.29.2

View File

@ -0,0 +1,166 @@
From 140f2cd50e9a10afcf10e76719d2810c6f8354a2 Mon Sep 17 00:00:00 2001
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: Fri, 4 Dec 2020 12:49:28 +0100
Subject: [PATCH] driver core: auxiliary bus: minor coding style tweaks
For some reason, the original aux bus patch had some really long lines
in a few places, probably due to it being a very long-lived patch in
development by many different people. Fix that up so that the two files
all have the same length lines and function formatting styles.
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Ertman <david.m.ertman@intel.com>
Cc: Fred Oh <fred.oh@linux.intel.com>
Cc: Kiran Patil <kiran.patil@intel.com>
Cc: Leon Romanovsky <leonro@nvidia.com>
Cc: Martin Habets <mhabets@solarflare.com>
Cc: Parav Pandit <parav@mellanox.com>
Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Cc: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Cc: Shiraz Saleem <shiraz.saleem@intel.com>
Link: https://lore.kernel.org/r/X8oiSFTpYHw1xE/o@kroah.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 0d2bf11a6b3e275a526b8d42d8d4a3a6067cf953)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/base/auxiliary.c | 58 +++++++++++++++++++----------------
include/linux/auxiliary_bus.h | 6 ++--
2 files changed, 35 insertions(+), 29 deletions(-)
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index c44e85802b43..f303daadf843 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -50,8 +50,8 @@ static int auxiliary_uevent(struct device *dev, struct kobj_uevent_env *env)
name = dev_name(dev);
p = strrchr(name, '.');
- return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX, (int)(p - name),
- name);
+ return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX,
+ (int)(p - name), name);
}
static const struct dev_pm_ops auxiliary_dev_pm_ops = {
@@ -113,16 +113,18 @@ static struct bus_type auxiliary_bus_type = {
* auxiliary_device_init - check auxiliary_device and initialize
* @auxdev: auxiliary device struct
*
- * This is the first step in the two-step process to register an auxiliary_device.
+ * This is the first step in the two-step process to register an
+ * auxiliary_device.
*
- * When this function returns an error code, then the device_initialize will *not* have
- * been performed, and the caller will be responsible to free any memory allocated for the
- * auxiliary_device in the error path directly.
+ * When this function returns an error code, then the device_initialize will
+ * *not* have been performed, and the caller will be responsible to free any
+ * memory allocated for the auxiliary_device in the error path directly.
*
- * It returns 0 on success. On success, the device_initialize has been performed. After this
- * point any error unwinding will need to include a call to auxiliary_device_uninit().
- * In this post-initialize error scenario, a call to the device's .release callback will be
- * triggered, and all memory clean-up is expected to be handled there.
+ * It returns 0 on success. On success, the device_initialize has been
+ * performed. After this point any error unwinding will need to include a call
+ * to auxiliary_device_uninit(). In this post-initialize error scenario, a call
+ * to the device's .release callback will be triggered, and all memory clean-up
+ * is expected to be handled there.
*/
int auxiliary_device_init(struct auxiliary_device *auxdev)
{
@@ -149,16 +151,19 @@ EXPORT_SYMBOL_GPL(auxiliary_device_init);
* @auxdev: auxiliary bus device to add to the bus
* @modname: name of the parent device's driver module
*
- * This is the second step in the two-step process to register an auxiliary_device.
+ * This is the second step in the two-step process to register an
+ * auxiliary_device.
*
- * This function must be called after a successful call to auxiliary_device_init(), which
- * will perform the device_initialize. This means that if this returns an error code, then a
- * call to auxiliary_device_uninit() must be performed so that the .release callback will
- * be triggered to free the memory associated with the auxiliary_device.
+ * This function must be called after a successful call to
+ * auxiliary_device_init(), which will perform the device_initialize. This
+ * means that if this returns an error code, then a call to
+ * auxiliary_device_uninit() must be performed so that the .release callback
+ * will be triggered to free the memory associated with the auxiliary_device.
*
- * The expectation is that users will call the "auxiliary_device_add" macro so that the caller's
- * KBUILD_MODNAME is automatically inserted for the modname parameter. Only if a user requires
- * a custom name would this version be called directly.
+ * The expectation is that users will call the "auxiliary_device_add" macro so
+ * that the caller's KBUILD_MODNAME is automatically inserted for the modname
+ * parameter. Only if a user requires a custom name would this version be
+ * called directly.
*/
int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname)
{
@@ -166,13 +171,13 @@ int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname)
int ret;
if (!modname) {
- pr_err("auxiliary device modname is NULL\n");
+ dev_err(dev, "auxiliary device modname is NULL\n");
return -EINVAL;
}
ret = dev_set_name(dev, "%s.%s.%d", modname, auxdev->name, auxdev->id);
if (ret) {
- pr_err("auxiliary device dev_set_name failed: %d\n", ret);
+ dev_err(dev, "auxiliary device dev_set_name failed: %d\n", ret);
return ret;
}
@@ -197,9 +202,9 @@ EXPORT_SYMBOL_GPL(__auxiliary_device_add);
* if it does. If the callback returns non-zero, this function will
* return to the caller and not iterate over any more devices.
*/
-struct auxiliary_device *
-auxiliary_find_device(struct device *start, const void *data,
- int (*match)(struct device *dev, const void *data))
+struct auxiliary_device *auxiliary_find_device(struct device *start,
+ const void *data,
+ int (*match)(struct device *dev, const void *data))
{
struct device *dev;
@@ -217,14 +222,15 @@ EXPORT_SYMBOL_GPL(auxiliary_find_device);
* @owner: owning module/driver
* @modname: KBUILD_MODNAME for parent driver
*/
-int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner,
- const char *modname)
+int __auxiliary_driver_register(struct auxiliary_driver *auxdrv,
+ struct module *owner, const char *modname)
{
if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table))
return -EINVAL;
if (auxdrv->name)
- auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname, auxdrv->name);
+ auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname,
+ auxdrv->name);
else
auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s", modname);
if (!auxdrv->driver.name)
diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h
index d67b17606210..fc51d45f106b 100644
--- a/include/linux/auxiliary_bus.h
+++ b/include/linux/auxiliary_bus.h
@@ -70,8 +70,8 @@ void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv);
#define module_auxiliary_driver(__auxiliary_driver) \
module_driver(__auxiliary_driver, auxiliary_driver_register, auxiliary_driver_unregister)
-struct auxiliary_device *
-auxiliary_find_device(struct device *start, const void *data,
- int (*match)(struct device *dev, const void *data));
+struct auxiliary_device *auxiliary_find_device(struct device *start,
+ const void *data,
+ int (*match)(struct device *dev, const void *data));
#endif /* _AUXILIARY_BUS_H_ */
--
2.29.2

View File

@ -0,0 +1,49 @@
From fb056562367fc8e65b4b7c7a2e0fabf4543c3533 Mon Sep 17 00:00:00 2001
From: Dave Jiang <dave.jiang@intel.com>
Date: Fri, 4 Dec 2020 09:46:49 -0700
Subject: [PATCH] driver core: auxiliary bus: Fix auxiliary bus shutdown null
auxdrv ptr
If the probe of the auxdrv failed, the device->driver is set to NULL.
During kernel shutdown, the bus shutdown will call auxdrv->shutdown and
cause an invalid ptr dereference. Add check to make sure device->driver is
not NULL before we proceed.
Fixes: 7de3697e9cbd ("Add auxiliary bus support")
Cc: Dave Ertman <david.m.ertman@intel.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Link: https://lore.kernel.org/r/160710040926.1889434.8840329810698403478.stgit@djiang5-desk3.ch.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 784b2c48ac12dcee27db001fb1a3c58c39380cb6)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/base/auxiliary.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index f303daadf843..8336535f1e11 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -92,10 +92,15 @@ static int auxiliary_bus_remove(struct device *dev)
static void auxiliary_bus_shutdown(struct device *dev)
{
- struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);
- struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
+ struct auxiliary_driver *auxdrv = NULL;
+ struct auxiliary_device *auxdev;
+
+ if (dev->driver) {
+ auxdrv = to_auxiliary_drv(dev->driver);
+ auxdev = to_auxiliary_dev(dev);
+ }
- if (auxdrv->shutdown)
+ if (auxdrv && auxdrv->shutdown)
auxdrv->shutdown(auxdev);
}
--
2.29.2

View File

@ -0,0 +1,146 @@
From 4e403070ed6ea6de90ef8e645dec23751018f504 Mon Sep 17 00:00:00 2001
From: Dave Jiang <dave.jiang@intel.com>
Date: Wed, 10 Feb 2021 13:16:11 -0700
Subject: [PATCH] driver core: auxiliary bus: Fix calling stage for auxiliary
bus init
When the auxiliary device code is built into the kernel, it can be executed
before the auxiliary bus is registered. This causes bus->p to be not
allocated and triggers a NULL pointer dereference when the auxiliary bus
device gets added with bus_add_device(). Call the auxiliary_bus_init()
under driver_init() so the bus is initialized before devices.
Below is the kernel splat for the bug:
[ 1.948215] BUG: kernel NULL pointer dereference, address: 0000000000000060
[ 1.950670] #PF: supervisor read access in kernel mode
[ 1.950670] #PF: error_code(0x0000) - not-present page
[ 1.950670] PGD 0
[ 1.950670] Oops: 0000 1 SMP NOPTI
[ 1.950670] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.10.0-intel-nextsvmtest+ #2205
[ 1.950670] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[ 1.950670] RIP: 0010:bus_add_device+0x64/0x140
[ 1.950670] Code: 00 49 8b 75 20 48 89 df e8 59 a1 ff ff 41 89 c4 85 c0 75 7b 48 8b 53 50 48 85 d2 75 03 48 8b 13 49 8b 85 a0 00 00 00 48 89 de <48> 8
78 60 48 83 c7 18 e8 ef d9 a9 ff 41 89 c4 85 c0 75 45 48 8b
[ 1.950670] RSP: 0000:ff46032ac001baf8 EFLAGS: 00010246
[ 1.950670] RAX: 0000000000000000 RBX: ff4597f7414aa680 RCX: 0000000000000000
[ 1.950670] RDX: ff4597f74142bbc0 RSI: ff4597f7414aa680 RDI: ff4597f7414aa680
[ 1.950670] RBP: ff46032ac001bb10 R08: 0000000000000044 R09: 0000000000000228
[ 1.950670] R10: ff4597f741141b30 R11: ff4597f740182a90 R12: 0000000000000000
[ 1.950670] R13: ffffffffa5e936c0 R14: 0000000000000000 R15: 0000000000000000
[ 1.950670] FS: 0000000000000000(0000) GS:ff4597f7bba00000(0000) knlGS:0000000000000000
[ 1.950670] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1.950670] CR2: 0000000000000060 CR3: 000000002140c001 CR4: 0000000000f71ef0
[ 1.950670] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 1.950670] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400
[ 1.950670] PKRU: 55555554
[ 1.950670] Call Trace:
[ 1.950670] device_add+0x3ee/0x850
[ 1.950670] __auxiliary_device_add+0x47/0x60
[ 1.950670] idxd_pci_probe+0xf77/0x1180
[ 1.950670] local_pci_probe+0x4a/0x90
[ 1.950670] pci_device_probe+0xff/0x1b0
[ 1.950670] really_probe+0x1cf/0x440
[ 1.950670] ? rdinit_setup+0x31/0x31
[ 1.950670] driver_probe_device+0xe8/0x150
[ 1.950670] device_driver_attach+0x58/0x60
[ 1.950670] __driver_attach+0x8f/0x150
[ 1.950670] ? device_driver_attach+0x60/0x60
[ 1.950670] ? device_driver_attach+0x60/0x60
[ 1.950670] bus_for_each_dev+0x79/0xc0
[ 1.950670] ? kmem_cache_alloc_trace+0x323/0x430
[ 1.950670] driver_attach+0x1e/0x20
[ 1.950670] bus_add_driver+0x154/0x1f0
[ 1.950670] driver_register+0x70/0xc0
[ 1.950670] __pci_register_driver+0x54/0x60
[ 1.950670] idxd_init_module+0xe2/0xfc
[ 1.950670] ? idma64_platform_driver_init+0x19/0x19
[ 1.950670] do_one_initcall+0x4a/0x1e0
[ 1.950670] kernel_init_freeable+0x1fc/0x25c
[ 1.950670] ? rest_init+0xba/0xba
[ 1.950670] kernel_init+0xe/0x116
[ 1.950670] ret_from_fork+0x1f/0x30
[ 1.950670] Modules linked in:
[ 1.950670] CR2: 0000000000000060
[ 1.950670] --[ end trace cd7d1b226d3ca901 ]--
Fixes: 7de3697e9cbd ("Add auxiliary bus support")
Reported-by: Jacob Pan <jacob.jun.pan@intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Acked-by: Dave Ertman <david.m.ertman@intel.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/20210210201611.1611074-1-dave.jiang@intel.com
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 471b12c43f376d5203dbff0e91316eea11f6f4df)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/base/auxiliary.c | 13 +++----------
drivers/base/base.h | 5 +++++
drivers/base/init.c | 1 +
3 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index 8336535f1e11..d8b314e7d0fd 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -15,6 +15,7 @@
#include <linux/pm_runtime.h>
#include <linux/string.h>
#include <linux/auxiliary_bus.h>
+#include "base.h"
static const struct auxiliary_device_id *auxiliary_match_id(const struct auxiliary_device_id *id,
const struct auxiliary_device *auxdev)
@@ -260,19 +261,11 @@ void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv)
}
EXPORT_SYMBOL_GPL(auxiliary_driver_unregister);
-static int __init auxiliary_bus_init(void)
+void __init auxiliary_bus_init(void)
{
- return bus_register(&auxiliary_bus_type);
+ WARN_ON(bus_register(&auxiliary_bus_type));
}
-static void __exit auxiliary_bus_exit(void)
-{
- bus_unregister(&auxiliary_bus_type);
-}
-
-module_init(auxiliary_bus_init);
-module_exit(auxiliary_bus_exit);
-
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Auxiliary Bus");
MODULE_AUTHOR("David Ertman <david.m.ertman@intel.com>");
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 91cfb8405abd..7d97447460fa 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -119,6 +119,11 @@ static inline int hypervisor_init(void) { return 0; }
extern int platform_bus_init(void);
extern void cpu_dev_init(void);
extern void container_dev_init(void);
+#ifdef CONFIG_AUXILIARY_BUS
+extern void auxiliary_bus_init(void);
+#else
+static inline void auxiliary_bus_init(void) { }
+#endif
struct kobject *virtual_device_parent(struct device *dev);
diff --git a/drivers/base/init.c b/drivers/base/init.c
index 908e6520e804..a9f57c22fb9e 100644
--- a/drivers/base/init.c
+++ b/drivers/base/init.c
@@ -32,6 +32,7 @@ void __init driver_init(void)
*/
of_core_init();
platform_bus_init();
+ auxiliary_bus_init();
cpu_dev_init();
memory_dev_init();
container_dev_init();
--
2.29.2

View File

@ -0,0 +1,35 @@
From 7739d61db7ae6d01e06f8fbc0feb089cebe84ebe Mon Sep 17 00:00:00 2001
From: Dave Jiang <dave.jiang@intel.com>
Date: Thu, 11 Feb 2021 13:21:29 -0700
Subject: [PATCH] driver core: auxiliary bus: Remove unneeded module bits
Remove module bits in the auxiliary bus code since the auxiliary bus
cannot be built as a module and the relevant code is not needed.
Cc: Dave Ertman <david.m.ertman@intel.com>
Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/161307488980.1896017.15627190714413338196.stgit@djiang5-desk3.ch.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit bbf44abeeabfe05a124535e6c3a9fd7d682d42bf)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/base/auxiliary.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index d8b314e7d0fd..adc199dfba3c 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -265,8 +265,3 @@ void __init auxiliary_bus_init(void)
{
WARN_ON(bus_register(&auxiliary_bus_type));
}
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Auxiliary Bus");
-MODULE_AUTHOR("David Ertman <david.m.ertman@intel.com>");
-MODULE_AUTHOR("Kiran Patil <kiran.patil@intel.com>");
--
2.29.2

View File

@ -0,0 +1,51 @@
From e4a05ae5a0d7fdaf8cfe7080640ce4a6057277c4 Mon Sep 17 00:00:00 2001
From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Date: Tue, 13 Jul 2021 12:34:38 +0300
Subject: [PATCH] driver core: auxiliary bus: Fix memory leak when
driver_register() fail
If driver_register() returns with error we need to free the memory
allocated for auxdrv->driver.name before returning from
__auxiliary_driver_register()
Fixes: 7de3697e9cbd4 ("Add auxiliary bus support")
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20210713093438.3173-1-peter.ujfalusi@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 4afa0c22eed33cfe0c590742387f0d16f32412f3)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/base/auxiliary.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index adc199dfba3c..6a30264ab2ba 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -231,6 +231,8 @@ EXPORT_SYMBOL_GPL(auxiliary_find_device);
int __auxiliary_driver_register(struct auxiliary_driver *auxdrv,
struct module *owner, const char *modname)
{
+ int ret;
+
if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table))
return -EINVAL;
@@ -246,7 +248,11 @@ int __auxiliary_driver_register(struct auxiliary_driver *auxdrv,
auxdrv->driver.bus = &auxiliary_bus_type;
auxdrv->driver.mod_name = modname;
- return driver_register(&auxdrv->driver);
+ ret = driver_register(&auxdrv->driver);
+ if (ret)
+ kfree(auxdrv->driver.name);
+
+ return ret;
}
EXPORT_SYMBOL_GPL(__auxiliary_driver_register);
--
2.29.2

View File

@ -0,0 +1,38 @@
From ccf9728c267d16dedb1b5d0ecd4518cac435fd02 Mon Sep 17 00:00:00 2001
From: "M. Vefa Bicakci" <vefa.bicakci@windriver.com>
Date: Thu, 17 Feb 2022 14:17:58 -0500
Subject: [PATCH] driver core: auxiliary bus: Enable by default
This commit enables CONFIG_AUXILIARY_BUS by default. This is necessary,
because StarlingX does not enable any kernel modules that 'select'
CONFIG_AUXILIARY_BUS, which causes the kernel's build system to
automatically disable this option.
However, StarlingX has out-of-tree users of this functionality (such as
the 'ice' and 'mlnx-ofa_kernel' out-of-tree kernel driver packages),
hence the need for this change. Prior to this commit, the aforementioned
out-of-tree kernel drivers would use their embedded/bundled copy of the
same functionality, which would cause kernel symbol conflicts at
run-time when users attempted to load both ice and mlnx-ofa_kernel
drivers.
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/base/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 040be48ce046..a18ec49b9dac 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -3,6 +3,7 @@ menu "Generic Driver Options"
config AUXILIARY_BUS
bool
+ default y
config UEVENT_HELPER
bool "Support for uevent helper"
--
2.29.2

View File

@ -9,3 +9,20 @@
0009-tpm-ignore-burstcount-to-improve-performance.patch
0010-restrict-iSCSI-kthreads-to-CPUs-in-cpu_kthread_mask.patch
0011-scsi-smartpqi-Enable-sas_address-sysfs-for-SATA.patch
0012-workqueue-Affine-rescuer-threads-and-unbound-wqs.patch
0013-rcu-Mark-accesses-to-rcu_state.n_force_qs.patch
0014-rcu-Tighten-rcu_advance_cbs_nowake-checks.patch
0015-Revert-scsi-sd-Inline-sd_probe_part2.patch
0016-Revert-commit-f049cf1a7b.patch
0017-genirq-Export-affinity-setter-for-modules.patch
0018-genirq-Provide-new-interfaces-for-affinity-hints.patch
0019-ixgbe-Use-irq_update_affinity_hint.patch
0020-Add-auxiliary-bus-support.patch
0021-driver-core-auxiliary-bus-move-slab.h-from-include-f.patch
0022-driver-core-auxiliary-bus-make-remove-function-retur.patch
0023-driver-core-auxiliary-bus-minor-coding-style-tweaks.patch
0024-driver-core-auxiliary-bus-Fix-auxiliary-bus-shutdown.patch
0025-driver-core-auxiliary-bus-Fix-calling-stage-for-auxi.patch
0026-driver-core-auxiliary-bus-Remove-unneeded-module-bit.patch
0027-driver-core-auxiliary-bus-Fix-memory-leak-when-drive.patch
0028-driver-core-auxiliary-bus-Enable-by-default.patch

File diff suppressed because it is too large Load Diff

View File

@ -3,3 +3,4 @@
0003-kernel-std-Add-a-kernel-config-file-for-stx-debian.patch
0004-kernel-std-Adapt-the-debian-folder-for-building-linu.patch
0005-kernel-modules-sign-kernel-modules.patch
0006-Debian-align-config-file-with-stx-centos.patch

View File

@ -1,4 +1,4 @@
From a04995a064c17b5e5df6d6f184c1cf01bb8bc6a0 Mon Sep 17 00:00:00 2001
From d4c6a64967be6e34fec40ddff5714efe001be7c3 Mon Sep 17 00:00:00 2001
From: Chris Friesen <chris.friesen@windriver.com>
Date: Tue, 24 Nov 2015 16:27:28 -0500
Subject: [PATCH] affine compute kernel threads
@ -31,19 +31,19 @@ Signed-off-by: Vefa Bicakci <vefa.bicakci@windriver.com>
[jm: Adapted the patch for context changes.]
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
---
.../admin-guide/kernel-parameters.txt | 10 ++++++++++
.../admin-guide/kernel-parameters.txt | 10 ++++++++
include/linux/cpumask.h | 3 +++
init/main.c | 2 ++
kernel/cpu.c | 19 +++++++++++++++++++
kernel/kthread.c | 5 ++---
kernel/cpu.c | 23 +++++++++++++++++++
kernel/kthread.c | 5 ++--
kernel/umh.c | 3 +++
6 files changed, 39 insertions(+), 3 deletions(-)
6 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 26bfe7ae711b..91bb37814527 100644
index 19e9e220eaa1..0260789adc94 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2217,6 +2217,16 @@
@@ -2223,6 +2223,16 @@
See also Documentation/trace/kprobetrace.rst "Kernel
Boot Parameter" section.
@ -86,10 +86,10 @@ index f0d895d6ac39..45f338cfdd6f 100644
extern atomic_t __num_online_cpus;
diff --git a/init/main.c b/init/main.c
index d9d914111251..951410241ef4 100644
index db693781a12f..4e7777bdab6e 100644
--- a/init/main.c
+++ b/init/main.c
@@ -1527,6 +1527,8 @@ static noinline void __init kernel_init_freeable(void)
@@ -1536,6 +1536,8 @@ static noinline void __init kernel_init_freeable(void)
do_basic_setup();
@ -99,10 +99,10 @@ index d9d914111251..951410241ef4 100644
console_on_rootfs();
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 2b8d7a5db383..b5dbec330189 100644
index 67c22941b5f2..67b1a67bd8f0 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -2449,6 +2449,25 @@ EXPORT_SYMBOL(__cpu_active_mask);
@@ -2498,6 +2498,29 @@ EXPORT_SYMBOL(__cpu_active_mask);
atomic_t __num_online_cpus __read_mostly;
EXPORT_SYMBOL(__num_online_cpus);
@ -112,15 +112,19 @@ index 2b8d7a5db383..b5dbec330189 100644
+
+static int __init kthread_setup(char *str)
+{
+ struct cpumask tmp_mask;
+ cpumask_var_t tmp_mask;
+ int err;
+
+ err = cpulist_parse(str, &tmp_mask);
+
+ alloc_bootmem_cpumask_var(&tmp_mask);
+
+ err = cpulist_parse(str, tmp_mask);
+ if (!err)
+ cpumask_copy(&__cpu_kthread_mask, &tmp_mask);
+ cpumask_copy(&__cpu_kthread_mask, tmp_mask);
+ else
+ pr_err("Cannot parse 'kthread_cpus=%s'; error %d\n", str, err);
+
+
+ free_bootmem_cpumask_var(tmp_mask);
+
+ return 1;
+}
+__setup("kthread_cpus=", kthread_setup);
@ -129,10 +133,10 @@ index 2b8d7a5db383..b5dbec330189 100644
{
cpumask_copy(&__cpu_present_mask, src);
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 5edf7e19ab26..7c3924752999 100644
index 508fe5278285..a7bb87b00cea 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -384,8 +384,7 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
@@ -405,8 +405,7 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
* The kernel thread should not inherit these properties.
*/
sched_setscheduler_nocheck(task, SCHED_NORMAL, &param);
@ -142,7 +146,7 @@ index 5edf7e19ab26..7c3924752999 100644
}
kfree(create);
return task;
@@ -634,7 +633,7 @@ int kthreadd(void *unused)
@@ -655,7 +654,7 @@ int kthreadd(void *unused)
/* Setup a clean context for our children to inherit. */
set_task_comm(tsk, "kthreadd");
ignore_signals(tsk);
@ -166,5 +170,5 @@ index 3f646613a9d3..e5027cee43f7 100644
* Our parent (unbound workqueue) runs with elevated scheduling
* priority. Avoid propagating that into the userspace child.
--
2.31.1
2.29.2

View File

@ -0,0 +1,61 @@
From ee39df8a1626eb35797b0f9943dc881752c36588 Mon Sep 17 00:00:00 2001
From: "M. Vefa Bicakci" <vefa.bicakci@windriver.com>
Date: Thu, 9 Sep 2021 04:56:46 -0400
Subject: [PATCH] workqueue: Affine rescuer threads and unbound wqs
This commit ensures that workqueue rescuer threads are affined to the
platform CPUs specified by the "kthread_cpus" kernel argument. Prior to
this commit, rescuer threads could be bound to any CPU. Rescuer threads
are described in "kernel/workqueue.c" as follows:
"Regular work processing on a pool may block trying to create a new
worker which uses GFP_KERNEL allocation which has slight chance of
developing into deadlock if some works currently on the same queue
need to be processed to satisfy the GFP_KERNEL allocation. This is
the problem rescuer solves.
When such condition is possible, the pool summons rescuers of all
workqueues which have works queued on the pool and let them process
those works so that forward progress can be guaranteed."
This commit also affines unbound workqueues to the platform CPUs instead
of the housekeeping CPUs, because the latter can be a superset of the
former.
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
---
kernel/workqueue.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index d6bdf3ad61e9..43f11a383cba 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -4242,7 +4242,7 @@ static int init_rescuer(struct workqueue_struct *wq)
}
wq->rescuer = rescuer;
- kthread_bind_mask(rescuer->task, cpu_possible_mask);
+ kthread_bind_mask(rescuer->task, cpu_kthread_mask);
wake_up_process(rescuer->task);
return 0;
@@ -5937,13 +5937,12 @@ static void __init wq_numa_init(void)
void __init workqueue_init_early(void)
{
int std_nice[NR_STD_WORKER_POOLS] = { 0, HIGHPRI_NICE_LEVEL };
- int hk_flags = HK_FLAG_DOMAIN | HK_FLAG_WQ;
int i, cpu;
BUILD_BUG_ON(__alignof__(struct pool_workqueue) < __alignof__(long long));
BUG_ON(!alloc_cpumask_var(&wq_unbound_cpumask, GFP_KERNEL));
- cpumask_copy(wq_unbound_cpumask, housekeeping_cpumask(hk_flags));
+ cpumask_copy(wq_unbound_cpumask, cpu_kthread_mask);
pwq_cache = KMEM_CACHE(pool_workqueue, SLAB_PANIC);
--
2.29.2

View File

@ -0,0 +1,64 @@
From e21cab0b7f1a6634ee57950600b68f6df960e3f5 Mon Sep 17 00:00:00 2001
From: "Paul E. McKenney" <paulmck@kernel.org>
Date: Tue, 20 Jul 2021 06:16:27 -0700
Subject: [PATCH] rcu: Mark accesses to rcu_state.n_force_qs
This commit marks accesses to the rcu_state.n_force_qs. These data
races are hard to make happen, but syzkaller was equal to the task.
Reported-by: syzbot+e08a83a1940ec3846cd5@syzkaller.appspotmail.com
Acked-by: Marco Elver <elver@google.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
(cherry picked from commit 2431774f04d1050292054c763070021bade7b151)
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
---
kernel/rcu/tree.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 4cc5af7f2b91..30cb9af8284c 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -1890,7 +1890,7 @@ static void rcu_gp_fqs(bool first_time)
struct rcu_node *rnp = rcu_get_root();
WRITE_ONCE(rcu_state.gp_activity, jiffies);
- rcu_state.n_force_qs++;
+ WRITE_ONCE(rcu_state.n_force_qs, rcu_state.n_force_qs + 1);
if (first_time) {
/* Collect dyntick-idle snapshots. */
force_qs_rnp(dyntick_save_progress_counter);
@@ -2532,7 +2532,7 @@ static void rcu_do_batch(struct rcu_data *rdp)
/* Reset ->qlen_last_fqs_check trigger if enough CBs have drained. */
if (count == 0 && rdp->qlen_last_fqs_check != 0) {
rdp->qlen_last_fqs_check = 0;
- rdp->n_force_qs_snap = rcu_state.n_force_qs;
+ rdp->n_force_qs_snap = READ_ONCE(rcu_state.n_force_qs);
} else if (count < rdp->qlen_last_fqs_check - qhimark)
rdp->qlen_last_fqs_check = count;
@@ -2878,10 +2878,10 @@ static void __call_rcu_core(struct rcu_data *rdp, struct rcu_head *head,
} else {
/* Give the grace period a kick. */
rdp->blimit = DEFAULT_MAX_RCU_BLIMIT;
- if (rcu_state.n_force_qs == rdp->n_force_qs_snap &&
+ if (READ_ONCE(rcu_state.n_force_qs) == rdp->n_force_qs_snap &&
rcu_segcblist_first_pend_cb(&rdp->cblist) != head)
rcu_force_quiescent_state();
- rdp->n_force_qs_snap = rcu_state.n_force_qs;
+ rdp->n_force_qs_snap = READ_ONCE(rcu_state.n_force_qs);
rdp->qlen_last_fqs_check = rcu_segcblist_n_cbs(&rdp->cblist);
}
}
@@ -3988,7 +3988,7 @@ int rcutree_prepare_cpu(unsigned int cpu)
/* Set up local state, ensuring consistent view of global state. */
raw_spin_lock_irqsave_rcu_node(rnp, flags);
rdp->qlen_last_fqs_check = 0;
- rdp->n_force_qs_snap = rcu_state.n_force_qs;
+ rdp->n_force_qs_snap = READ_ONCE(rcu_state.n_force_qs);
rdp->blimit = blimit;
if (rcu_segcblist_empty(&rdp->cblist) && /* No early-boot CBs? */
!rcu_segcblist_is_offloaded(&rdp->cblist))
--
2.31.1

View File

@ -0,0 +1,45 @@
From 21e034adb9df3581fda926a29b3a11bda38ba93b Mon Sep 17 00:00:00 2001
From: "Paul E. McKenney" <paulmck@kernel.org>
Date: Fri, 17 Sep 2021 15:04:48 -0700
Subject: [PATCH] rcu: Tighten rcu_advance_cbs_nowake() checks
Currently, rcu_advance_cbs_nowake() checks that a grace period is in
progress, however, that grace period could end just after the check.
This commit rechecks that a grace period is still in progress the lock.
The grace period cannot end while the current CPU's rcu_node structure's
->lock is held, thus avoiding false positives from the WARN_ON_ONCE().
As Daniel Vacek noted, it is not necessary for the rcu_node structure
to have a CPU that has not yet passed through its quiescent state.
Tested-By: Guillaume Morin <guillaume@morinfr.org>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
(Cherry pick from https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/
linux-rcu.git/commit/?h=rcu/next&id=325a2030b90376d179a129794e2fae2b24d73923)
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
---
kernel/rcu/tree.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index ef8d36f580fc..8706b30c2ac8 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -1590,10 +1590,11 @@ static void __maybe_unused rcu_advance_cbs_nowake(struct rcu_node *rnp,
struct rcu_data *rdp)
{
rcu_lockdep_assert_cblist_protected(rdp);
- if (!rcu_seq_state(rcu_seq_current(&rnp->gp_seq)) ||
- !raw_spin_trylock_rcu_node(rnp))
+ if (!rcu_seq_state(rcu_seq_current(&rnp->gp_seq)) || !raw_spin_trylock_rcu_node(rnp))
return;
- WARN_ON_ONCE(rcu_advance_cbs(rnp, rdp));
+ // The grace period cannot end while we hold the rcu_node lock.
+ if (rcu_seq_state(rcu_seq_current(&rnp->gp_seq)))
+ WARN_ON_ONCE(rcu_advance_cbs(rnp, rdp));
raw_spin_unlock_rcu_node(rnp);
}
--
2.31.1

View File

@ -0,0 +1,167 @@
From 42f1ccc21f873a27c125a4e1aa3cb70a2336aa14 Mon Sep 17 00:00:00 2001
From: Jiping Ma <jiping.ma2@windriver.com>
Date: Wed, 8 Dec 2021 17:49:56 -0800
Subject: [PATCH] Revert "scsi: sd: Inline sd_probe_part2()"
This reverts commit 82a54da641f3cacfa31db36fc58a5e903f804c22.
Merge conflicts were encountered when reverting this commit, which
inlines sd_probe_part2() into sd_probe(). However, the inlined parts
of sd_probe_part2() have since been modified. To avoid a difference
in behaviour, the updated code was relocated to sd_probe_part2().
The inlined code has been modified as follows since the inlining
happened:
The following code was added
if (sdp->rpm_autosuspend) {
pm_runtime_set_autosuspend_delay(dev,
sdp->host->hostt->rpm_autosuspend_delay);
}
between the following line
blk_pm_runtime_init(sdp->request_queue, dev);
and the following line
device_add_disk(dev, gd, NULL);
In addition, init_opal_dev() is now passed the pointer "sdkp"
instead of "sdp" as the first argument. This commit ensures that
these two changes were accounted for when reverting the inlining
of sd_probe_part2().
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
---
drivers/scsi/sd.c | 111 ++++++++++++++++++++++++++--------------------
1 file changed, 63 insertions(+), 48 deletions(-)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 56e291708587..d1d27516fc6a 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -3364,6 +3364,68 @@ static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen)
return 0;
}
+static void sd_probe_part2(struct scsi_disk *sdkp)
+{
+ struct scsi_device *sdp;
+ struct gendisk *gd;
+ u32 index;
+ struct device *dev;
+
+ sdp = sdkp->device;
+ gd = sdkp->disk;
+ index = sdkp->index;
+ dev = &sdp->sdev_gendev;
+
+ gd->major = sd_major((index & 0xf0) >> 4);
+ gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
+
+ gd->fops = &sd_fops;
+ gd->private_data = &sdkp->driver;
+ gd->queue = sdkp->device->request_queue;
+
+ /* defaults, until the device tells us otherwise */
+ sdp->sector_size = 512;
+ sdkp->capacity = 0;
+ sdkp->media_present = 1;
+ sdkp->write_prot = 0;
+ sdkp->cache_override = 0;
+ sdkp->WCE = 0;
+ sdkp->RCD = 0;
+ sdkp->ATO = 0;
+ sdkp->first_scan = 1;
+ sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS;
+
+ sd_revalidate_disk(gd);
+
+ gd->flags = GENHD_FL_EXT_DEVT;
+ if (sdp->removable) {
+ gd->flags |= GENHD_FL_REMOVABLE;
+ gd->events |= DISK_EVENT_MEDIA_CHANGE;
+ gd->event_flags = DISK_EVENT_FLAG_POLL | DISK_EVENT_FLAG_UEVENT;
+ }
+
+ blk_pm_runtime_init(sdp->request_queue, dev);
+ if (sdp->rpm_autosuspend) {
+ pm_runtime_set_autosuspend_delay(dev,
+ sdp->host->hostt->rpm_autosuspend_delay);
+ }
+ device_add_disk(dev, gd, NULL);
+ if (sdkp->capacity)
+ sd_dif_config_host(sdkp);
+
+ sd_revalidate_disk(gd);
+
+ if (sdkp->security) {
+ sdkp->opal_dev = init_opal_dev(sdkp, &sd_sec_submit);
+ if (sdkp->opal_dev)
+ sd_printk(KERN_NOTICE, sdkp, "supports TCG Opal\n");
+ }
+
+ sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
+ sdp->removable ? "removable " : "");
+ scsi_autopm_put_device(sdp);
+}
+
/**
* sd_probe - called during driver initialization and whenever a
* new scsi device is attached to the system. It is called once
@@ -3455,54 +3517,7 @@ static int sd_probe(struct device *dev)
dev_set_drvdata(dev, sdkp);
- gd->major = sd_major((index & 0xf0) >> 4);
- gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
-
- gd->fops = &sd_fops;
- gd->private_data = &sdkp->driver;
- gd->queue = sdkp->device->request_queue;
-
- /* defaults, until the device tells us otherwise */
- sdp->sector_size = 512;
- sdkp->capacity = 0;
- sdkp->media_present = 1;
- sdkp->write_prot = 0;
- sdkp->cache_override = 0;
- sdkp->WCE = 0;
- sdkp->RCD = 0;
- sdkp->ATO = 0;
- sdkp->first_scan = 1;
- sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS;
-
- sd_revalidate_disk(gd);
-
- gd->flags = GENHD_FL_EXT_DEVT;
- if (sdp->removable) {
- gd->flags |= GENHD_FL_REMOVABLE;
- gd->events |= DISK_EVENT_MEDIA_CHANGE;
- gd->event_flags = DISK_EVENT_FLAG_POLL | DISK_EVENT_FLAG_UEVENT;
- }
-
- blk_pm_runtime_init(sdp->request_queue, dev);
- if (sdp->rpm_autosuspend) {
- pm_runtime_set_autosuspend_delay(dev,
- sdp->host->hostt->rpm_autosuspend_delay);
- }
- device_add_disk(dev, gd, NULL);
- if (sdkp->capacity)
- sd_dif_config_host(sdkp);
-
- sd_revalidate_disk(gd);
-
- if (sdkp->security) {
- sdkp->opal_dev = init_opal_dev(sdkp, &sd_sec_submit);
- if (sdkp->opal_dev)
- sd_printk(KERN_NOTICE, sdkp, "supports TCG Opal\n");
- }
-
- sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
- sdp->removable ? "removable " : "");
- scsi_autopm_put_device(sdp);
+ sd_probe_part2(sdkp);
return 0;
--
2.31.1

View File

@ -0,0 +1,135 @@
From b5dad6e67f9704968ca7d4daf1715667cddafa3d Mon Sep 17 00:00:00 2001
From: Jiping Ma <jiping.ma2@windriver.com>
Date: Wed, 8 Dec 2021 18:34:59 -0800
Subject: [PATCH 2/2] Revert commit f049cf1a7b
commit f049cf1a7b "scsi: sd: Rely on the driver core for asynchronous
probing"
This reverts commit f049cf1a7b6737c75884247c3f6383ef104d255a,
and it is a clean revert, there is not any conflict.
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
---
drivers/scsi/scsi.c | 12 +++++++++---
drivers/scsi/scsi_pm.c | 6 +++++-
drivers/scsi/scsi_priv.h | 1 +
drivers/scsi/sd.c | 12 +++++++++---
4 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 24619c3bebd5..3080292a16cd 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -86,10 +86,15 @@ unsigned int scsi_logging_level;
EXPORT_SYMBOL(scsi_logging_level);
#endif
+/* sd, scsi core and power management need to coordinate flushing async actions */
+ASYNC_DOMAIN(scsi_sd_probe_domain);
+EXPORT_SYMBOL(scsi_sd_probe_domain);
+
/*
- * Domain for asynchronous system resume operations. It is marked 'exclusive'
- * to avoid being included in the async_synchronize_full() that is invoked by
- * dpm_resume().
+ * Separate domain (from scsi_sd_probe_domain) to maximize the benefit of
+ * asynchronous system resume operations. It is marked 'exclusive' to avoid
+ * being included in the async_synchronize_full() that is invoked by
+ * dpm_resume()
*/
ASYNC_DOMAIN_EXCLUSIVE(scsi_sd_pm_domain);
EXPORT_SYMBOL(scsi_sd_pm_domain);
@@ -799,6 +804,7 @@ static void __exit exit_scsi(void)
scsi_exit_devinfo();
scsi_exit_procfs();
scsi_exit_queue();
+ async_unregister_domain(&scsi_sd_probe_domain);
}
subsys_initcall(init_scsi);
diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
index 3717eea37ecb..b3d71b516213 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -175,7 +175,11 @@ static int scsi_bus_resume_common(struct device *dev,
static int scsi_bus_prepare(struct device *dev)
{
- if (scsi_is_host_device(dev)) {
+ if (scsi_is_sdev_device(dev)) {
+ /* sd probing uses async_schedule. Wait until it finishes. */
+ async_synchronize_full_domain(&scsi_sd_probe_domain);
+
+ } else if (scsi_is_host_device(dev)) {
/* Wait until async scanning is finished */
scsi_complete_async_scans();
}
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index 180636d54982..c43456f0870c 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -172,6 +172,7 @@ static inline void scsi_autopm_put_host(struct Scsi_Host *h) {}
#endif /* CONFIG_PM */
extern struct async_domain scsi_sd_pm_domain;
+extern struct async_domain scsi_sd_probe_domain;
/* scsi_dh.c */
#ifdef CONFIG_SCSI_DH
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 2e22ee4501e7..e6c70475f084 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -616,7 +616,6 @@ static struct scsi_driver sd_template = {
.name = "sd",
.owner = THIS_MODULE,
.probe = sd_probe,
- .probe_type = PROBE_PREFER_ASYNCHRONOUS,
.remove = sd_remove,
.shutdown = sd_shutdown,
.pm = &sd_pm_ops,
@@ -3364,8 +3363,12 @@ static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen)
return 0;
}
-static void sd_probe_part2(struct scsi_disk *sdkp)
+/*
+ * The asynchronous part of sd_probe
+ */
+static void sd_probe_async(void *data, async_cookie_t cookie)
{
+ struct scsi_disk *sdkp = data;
struct scsi_device *sdp;
struct gendisk *gd;
u32 index;
@@ -3424,6 +3427,7 @@ static void sd_probe_part2(struct scsi_disk *sdkp)
sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
sdp->removable ? "removable " : "");
scsi_autopm_put_device(sdp);
+ put_device(&sdkp->dev);
}
/**
@@ -3517,7 +3521,8 @@ static int sd_probe(struct device *dev)
dev_set_drvdata(dev, sdkp);
- sd_probe_part2(sdkp);
+ get_device(&sdkp->dev); /* prevent release before async_schedule */
+ async_schedule_domain(sd_probe_async, sdkp, &scsi_sd_probe_domain);
return 0;
@@ -3554,6 +3559,7 @@ static int sd_remove(struct device *dev)
scsi_autopm_get_device(sdkp->device);
async_synchronize_full_domain(&scsi_sd_pm_domain);
+ async_synchronize_full_domain(&scsi_sd_probe_domain);
device_del(&sdkp->dev);
del_gendisk(sdkp->disk);
sd_shutdown(dev);
--
2.31.1

View File

@ -0,0 +1,124 @@
From 7c2dc6277376104f8cfe7f8d07c77f6d7155fb73 Mon Sep 17 00:00:00 2001
From: Thomas Gleixner <tglx@linutronix.de>
Date: Tue, 18 May 2021 11:17:26 +0200
Subject: [PATCH] genirq: Export affinity setter for modules
Perf modules abuse irq_set_affinity_hint() to set the affinity of system
PMU interrupts just because irq_set_affinity() was not exported.
The fact that irq_set_affinity_hint() actually sets the affinity is a
non-documented side effect and the name is clearly saying it's a hint.
To clean this up, export the real affinity setter.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Link: https://lore.kernel.org/r/20210518093117.968251441@linutronix.de
(cherry picked from commit 4d80d6ca5d77fde9880da8466e5b64f250e5bf82)
[mvb: Adjust context for a function that does not exist in v5.10.]
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
include/linux/interrupt.h | 35 ++---------------------------------
kernel/irq/manage.c | 33 ++++++++++++++++++++++++++++++++-
2 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index ee8299eb1f52..087a1cfad35c 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -314,39 +314,8 @@ struct irq_affinity_desc {
extern cpumask_var_t irq_default_affinity;
-/* Internal implementation. Use the helpers below */
-extern int __irq_set_affinity(unsigned int irq, const struct cpumask *cpumask,
- bool force);
-
-/**
- * irq_set_affinity - Set the irq affinity of a given irq
- * @irq: Interrupt to set affinity
- * @cpumask: cpumask
- *
- * Fails if cpumask does not contain an online CPU
- */
-static inline int
-irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
-{
- return __irq_set_affinity(irq, cpumask, false);
-}
-
-/**
- * irq_force_affinity - Force the irq affinity of a given irq
- * @irq: Interrupt to set affinity
- * @cpumask: cpumask
- *
- * Same as irq_set_affinity, but without checking the mask against
- * online cpus.
- *
- * Solely for low level cpu hotplug code, where we need to make per
- * cpu interrupts affine before the cpu becomes online.
- */
-static inline int
-irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
-{
- return __irq_set_affinity(irq, cpumask, true);
-}
+extern int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask);
+extern int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask);
extern int irq_can_set_affinity(unsigned int irq);
extern int irq_select_affinity(unsigned int irq);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 420b5ce0bf89..eeedb6224e2f 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -371,7 +371,8 @@ int irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask,
return ret;
}
-int __irq_set_affinity(unsigned int irq, const struct cpumask *mask, bool force)
+static int __irq_set_affinity(unsigned int irq, const struct cpumask *mask,
+ bool force)
{
struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
@@ -386,6 +387,36 @@ int __irq_set_affinity(unsigned int irq, const struct cpumask *mask, bool force)
return ret;
}
+/**
+ * irq_set_affinity - Set the irq affinity of a given irq
+ * @irq: Interrupt to set affinity
+ * @cpumask: cpumask
+ *
+ * Fails if cpumask does not contain an online CPU
+ */
+int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+{
+ return __irq_set_affinity(irq, cpumask, false);
+}
+EXPORT_SYMBOL_GPL(irq_set_affinity);
+
+/**
+ * irq_force_affinity - Force the irq affinity of a given irq
+ * @irq: Interrupt to set affinity
+ * @cpumask: cpumask
+ *
+ * Same as irq_set_affinity, but without checking the mask against
+ * online cpus.
+ *
+ * Solely for low level cpu hotplug code, where we need to make per
+ * cpu interrupts affine before the cpu becomes online.
+ */
+int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
+{
+ return __irq_set_affinity(irq, cpumask, true);
+}
+EXPORT_SYMBOL_GPL(irq_force_affinity);
+
int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
{
unsigned long flags;
--
2.29.2

View File

@ -0,0 +1,146 @@
From d4b260fea6b5d7f0da84236f97b385312ab2e0ac Mon Sep 17 00:00:00 2001
From: Thomas Gleixner <tglx@linutronix.de>
Date: Fri, 3 Sep 2021 11:24:17 -0400
Subject: [PATCH] genirq: Provide new interfaces for affinity hints
The discussion about removing the side effect of irq_set_affinity_hint() of
actually applying the cpumask (if not NULL) as affinity to the interrupt,
unearthed a few unpleasantries:
1) The modular perf drivers rely on the current behaviour for the very
wrong reasons.
2) While none of the other drivers prevents user space from changing
the affinity, a cursorily inspection shows that there are at least
expectations in some drivers.
#1 needs to be cleaned up anyway, so that's not a problem
#2 might result in subtle regressions especially when irqbalanced (which
nowadays ignores the affinity hint) is disabled.
Provide new interfaces:
irq_update_affinity_hint() - Only sets the affinity hint pointer
irq_set_affinity_and_hint() - Set the pointer and apply the affinity to
the interrupt
Make irq_set_affinity_hint() a wrapper around irq_apply_affinity_hint() and
document it to be phased out.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Nitesh Narayan Lal <nitesh@redhat.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20210501021832.743094-1-jesse.brandeburg@intel.com
Link: https://lore.kernel.org/r/20210903152430.244937-2-nitesh@redhat.com
(cherry picked from commit 65c7cdedeb3026fabcc967a7aae2f755ad4d0783)
[mvb: Adapt to v5.10 by resolving a minor merge conflict.]
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
include/linux/interrupt.h | 52 ++++++++++++++++++++++++++++++++++++++-
kernel/irq/manage.c | 8 +++---
2 files changed, 55 insertions(+), 5 deletions(-)
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 087a1cfad35c..72350bdee846 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -320,7 +320,45 @@ extern int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask);
extern int irq_can_set_affinity(unsigned int irq);
extern int irq_select_affinity(unsigned int irq);
-extern int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m);
+extern int __irq_apply_affinity_hint(unsigned int irq, const struct cpumask *m,
+ bool setaffinity);
+
+/**
+ * irq_update_affinity_hint - Update the affinity hint
+ * @irq: Interrupt to update
+ * @m: cpumask pointer (NULL to clear the hint)
+ *
+ * Updates the affinity hint, but does not change the affinity of the interrupt.
+ */
+static inline int
+irq_update_affinity_hint(unsigned int irq, const struct cpumask *m)
+{
+ return __irq_apply_affinity_hint(irq, m, false);
+}
+
+/**
+ * irq_set_affinity_and_hint - Update the affinity hint and apply the provided
+ * cpumask to the interrupt
+ * @irq: Interrupt to update
+ * @m: cpumask pointer (NULL to clear the hint)
+ *
+ * Updates the affinity hint and if @m is not NULL it applies it as the
+ * affinity of that interrupt.
+ */
+static inline int
+irq_set_affinity_and_hint(unsigned int irq, const struct cpumask *m)
+{
+ return __irq_apply_affinity_hint(irq, m, true);
+}
+
+/*
+ * Deprecated. Use irq_update_affinity_hint() or irq_set_affinity_and_hint()
+ * instead.
+ */
+static inline int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
+{
+ return irq_set_affinity_and_hint(irq, m);
+}
extern int
irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify);
@@ -350,6 +388,18 @@ static inline int irq_can_set_affinity(unsigned int irq)
static inline int irq_select_affinity(unsigned int irq) { return 0; }
+static inline int irq_update_affinity_hint(unsigned int irq,
+ const struct cpumask *m)
+{
+ return -EINVAL;
+}
+
+static inline int irq_set_affinity_and_hint(unsigned int irq,
+ const struct cpumask *m)
+{
+ return -EINVAL;
+}
+
static inline int irq_set_affinity_hint(unsigned int irq,
const struct cpumask *m)
{
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index eeedb6224e2f..63e7de3683d2 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -417,7 +417,8 @@ int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
}
EXPORT_SYMBOL_GPL(irq_force_affinity);
-int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
+int __irq_apply_affinity_hint(unsigned int irq, const struct cpumask *m,
+ bool setaffinity)
{
unsigned long flags;
struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
@@ -426,12 +427,11 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
return -EINVAL;
desc->affinity_hint = m;
irq_put_desc_unlock(desc, flags);
- /* set the initial affinity to prevent every interrupt being on CPU0 */
- if (m)
+ if (m && setaffinity)
__irq_set_affinity(irq, m, false);
return 0;
}
-EXPORT_SYMBOL_GPL(irq_set_affinity_hint);
+EXPORT_SYMBOL_GPL(__irq_apply_affinity_hint);
static void irq_affinity_notify(struct work_struct *work)
{
--
2.29.2

View File

@ -0,0 +1,64 @@
From 07298341feaa2c35fdd225735b4ee5299efb112f Mon Sep 17 00:00:00 2001
From: Nitesh Narayan Lal <nitesh@redhat.com>
Date: Fri, 3 Sep 2021 11:24:25 -0400
Subject: [PATCH] ixgbe: Use irq_update_affinity_hint()
The driver uses irq_set_affinity_hint() to update the affinity_hint mask
that is consumed by the userspace to distribute the interrupts. However,
under the hood irq_set_affinity_hint() also applies the provided cpumask
(if not NULL) as the affinity for the given interrupt which is an
undocumented side effect.
To remove this side effect irq_set_affinity_hint() has been marked
as deprecated and new interfaces have been introduced. Hence, replace the
irq_set_affinity_hint() with the new interface irq_update_affinity_hint()
that only updates the affinity_hint pointer.
Signed-off-by: Nitesh Narayan Lal <nitesh@redhat.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Link: https://lore.kernel.org/r/20210903152430.244937-10-nitesh@redhat.com
(cherry picked from commit cc493264c01d055742a34cfbaecaffb258dcc58c)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index ffe322136c58..fe10776d8479 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3250,8 +3250,8 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
/* If Flow Director is enabled, set interrupt affinity */
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) {
/* assign the mask for this irq */
- irq_set_affinity_hint(entry->vector,
- &q_vector->affinity_mask);
+ irq_update_affinity_hint(entry->vector,
+ &q_vector->affinity_mask);
}
}
@@ -3267,8 +3267,8 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
free_queue_irqs:
while (vector) {
vector--;
- irq_set_affinity_hint(adapter->msix_entries[vector].vector,
- NULL);
+ irq_update_affinity_hint(adapter->msix_entries[vector].vector,
+ NULL);
free_irq(adapter->msix_entries[vector].vector,
adapter->q_vector[vector]);
}
@@ -3401,7 +3401,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
continue;
/* clear the affinity_mask in the IRQ descriptor */
- irq_set_affinity_hint(entry->vector, NULL);
+ irq_update_affinity_hint(entry->vector, NULL);
free_irq(entry->vector, q_vector);
}
--
2.29.2

View File

@ -0,0 +1,743 @@
From a6492f505f12f830372636043098ad9dab3607d6 Mon Sep 17 00:00:00 2001
From: Dave Ertman <david.m.ertman@intel.com>
Date: Wed, 2 Dec 2020 16:54:24 -0800
Subject: [PATCH] Add auxiliary bus support
Add support for the Auxiliary Bus, auxiliary_device and auxiliary_driver.
It enables drivers to create an auxiliary_device and bind an
auxiliary_driver to it.
The bus supports probe/remove shutdown and suspend/resume callbacks.
Each auxiliary_device has a unique string based id; driver binds to
an auxiliary_device based on this id through the bus.
Co-developed-by: Kiran Patil <kiran.patil@intel.com>
Co-developed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Co-developed-by: Fred Oh <fred.oh@linux.intel.com>
Co-developed-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Kiran Patil <kiran.patil@intel.com>
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Fred Oh <fred.oh@linux.intel.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Dave Ertman <david.m.ertman@intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Shiraz Saleem <shiraz.saleem@intel.com>
Reviewed-by: Parav Pandit <parav@mellanox.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Martin Habets <mhabets@solarflare.com>
Link: https://lore.kernel.org/r/20201113161859.1775473-2-david.m.ertman@intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Link: https://lore.kernel.org/r/160695681289.505290.8978295443574440604.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 7de3697e9cbd4bd3d62bafa249d57990e1b8f294)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
Documentation/driver-api/auxiliary_bus.rst | 234 ++++++++++++++++++
Documentation/driver-api/index.rst | 1 +
drivers/base/Kconfig | 3 +
drivers/base/Makefile | 1 +
drivers/base/auxiliary.c | 268 +++++++++++++++++++++
include/linux/auxiliary_bus.h | 78 ++++++
include/linux/mod_devicetable.h | 8 +
scripts/mod/devicetable-offsets.c | 3 +
scripts/mod/file2alias.c | 8 +
9 files changed, 604 insertions(+)
create mode 100644 Documentation/driver-api/auxiliary_bus.rst
create mode 100644 drivers/base/auxiliary.c
create mode 100644 include/linux/auxiliary_bus.h
diff --git a/Documentation/driver-api/auxiliary_bus.rst b/Documentation/driver-api/auxiliary_bus.rst
new file mode 100644
index 000000000000..5dd7804631ef
--- /dev/null
+++ b/Documentation/driver-api/auxiliary_bus.rst
@@ -0,0 +1,234 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+=============
+Auxiliary Bus
+=============
+
+In some subsystems, the functionality of the core device (PCI/ACPI/other) is
+too complex for a single device to be managed by a monolithic driver
+(e.g. Sound Open Firmware), multiple devices might implement a common
+intersection of functionality (e.g. NICs + RDMA), or a driver may want to
+export an interface for another subsystem to drive (e.g. SIOV Physical Function
+export Virtual Function management). A split of the functinoality into child-
+devices representing sub-domains of functionality makes it possible to
+compartmentalize, layer, and distribute domain-specific concerns via a Linux
+device-driver model.
+
+An example for this kind of requirement is the audio subsystem where a single
+IP is handling multiple entities such as HDMI, Soundwire, local devices such as
+mics/speakers etc. The split for the core's functionality can be arbitrary or
+be defined by the DSP firmware topology and include hooks for test/debug. This
+allows for the audio core device to be minimal and focused on hardware-specific
+control and communication.
+
+Each auxiliary_device represents a part of its parent functionality. The
+generic behavior can be extended and specialized as needed by encapsulating an
+auxiliary_device within other domain-specific structures and the use of .ops
+callbacks. Devices on the auxiliary bus do not share any structures and the use
+of a communication channel with the parent is domain-specific.
+
+Note that ops are intended as a way to augment instance behavior within a class
+of auxiliary devices, it is not the mechanism for exporting common
+infrastructure from the parent. Consider EXPORT_SYMBOL_NS() to convey
+infrastructure from the parent module to the auxiliary module(s).
+
+
+When Should the Auxiliary Bus Be Used
+=====================================
+
+The auxiliary bus is to be used when a driver and one or more kernel modules,
+who share a common header file with the driver, need a mechanism to connect and
+provide access to a shared object allocated by the auxiliary_device's
+registering driver. The registering driver for the auxiliary_device(s) and the
+kernel module(s) registering auxiliary_drivers can be from the same subsystem,
+or from multiple subsystems.
+
+The emphasis here is on a common generic interface that keeps subsystem
+customization out of the bus infrastructure.
+
+One example is a PCI network device that is RDMA-capable and exports a child
+device to be driven by an auxiliary_driver in the RDMA subsystem. The PCI
+driver allocates and registers an auxiliary_device for each physical
+function on the NIC. The RDMA driver registers an auxiliary_driver that claims
+each of these auxiliary_devices. This conveys data/ops published by the parent
+PCI device/driver to the RDMA auxiliary_driver.
+
+Another use case is for the PCI device to be split out into multiple sub
+functions. For each sub function an auxiliary_device is created. A PCI sub
+function driver binds to such devices that creates its own one or more class
+devices. A PCI sub function auxiliary device is likely to be contained in a
+struct with additional attributes such as user defined sub function number and
+optional attributes such as resources and a link to the parent device. These
+attributes could be used by systemd/udev; and hence should be initialized
+before a driver binds to an auxiliary_device.
+
+A key requirement for utilizing the auxiliary bus is that there is no
+dependency on a physical bus, device, register accesses or regmap support.
+These individual devices split from the core cannot live on the platform bus as
+they are not physical devices that are controlled by DT/ACPI. The same
+argument applies for not using MFD in this scenario as MFD relies on individual
+function devices being physical devices.
+
+Auxiliary Device
+================
+
+An auxiliary_device represents a part of its parent device's functionality. It
+is given a name that, combined with the registering drivers KBUILD_MODNAME,
+creates a match_name that is used for driver binding, and an id that combined
+with the match_name provide a unique name to register with the bus subsystem.
+
+Registering an auxiliary_device is a two-step process. First call
+auxiliary_device_init(), which checks several aspects of the auxiliary_device
+struct and performs a device_initialize(). After this step completes, any
+error state must have a call to auxiliary_device_uninit() in its resolution path.
+The second step in registering an auxiliary_device is to perform a call to
+auxiliary_device_add(), which sets the name of the device and add the device to
+the bus.
+
+Unregistering an auxiliary_device is also a two-step process to mirror the
+register process. First call auxiliary_device_delete(), then call
+auxiliary_device_uninit().
+
+.. code-block:: c
+
+ struct auxiliary_device {
+ struct device dev;
+ const char *name;
+ u32 id;
+ };
+
+If two auxiliary_devices both with a match_name "mod.foo" are registered onto
+the bus, they must have unique id values (e.g. "x" and "y") so that the
+registered devices names are "mod.foo.x" and "mod.foo.y". If match_name + id
+are not unique, then the device_add fails and generates an error message.
+
+The auxiliary_device.dev.type.release or auxiliary_device.dev.release must be
+populated with a non-NULL pointer to successfully register the auxiliary_device.
+
+The auxiliary_device.dev.parent must also be populated.
+
+Auxiliary Device Memory Model and Lifespan
+------------------------------------------
+
+The registering driver is the entity that allocates memory for the
+auxiliary_device and register it on the auxiliary bus. It is important to note
+that, as opposed to the platform bus, the registering driver is wholly
+responsible for the management for the memory used for the driver object.
+
+A parent object, defined in the shared header file, contains the
+auxiliary_device. It also contains a pointer to the shared object(s), which
+also is defined in the shared header. Both the parent object and the shared
+object(s) are allocated by the registering driver. This layout allows the
+auxiliary_driver's registering module to perform a container_of() call to go
+from the pointer to the auxiliary_device, that is passed during the call to the
+auxiliary_driver's probe function, up to the parent object, and then have
+access to the shared object(s).
+
+The memory for the auxiliary_device is freed only in its release() callback
+flow as defined by its registering driver.
+
+The memory for the shared object(s) must have a lifespan equal to, or greater
+than, the lifespan of the memory for the auxiliary_device. The auxiliary_driver
+should only consider that this shared object is valid as long as the
+auxiliary_device is still registered on the auxiliary bus. It is up to the
+registering driver to manage (e.g. free or keep available) the memory for the
+shared object beyond the life of the auxiliary_device.
+
+The registering driver must unregister all auxiliary devices before its own
+driver.remove() is completed.
+
+Auxiliary Drivers
+=================
+
+Auxiliary drivers follow the standard driver model convention, where
+discovery/enumeration is handled by the core, and drivers
+provide probe() and remove() methods. They support power management
+and shutdown notifications using the standard conventions.
+
+.. code-block:: c
+
+ struct auxiliary_driver {
+ int (*probe)(struct auxiliary_device *,
+ const struct auxiliary_device_id *id);
+ int (*remove)(struct auxiliary_device *);
+ void (*shutdown)(struct auxiliary_device *);
+ int (*suspend)(struct auxiliary_device *, pm_message_t);
+ int (*resume)(struct auxiliary_device *);
+ struct device_driver driver;
+ const struct auxiliary_device_id *id_table;
+ };
+
+Auxiliary drivers register themselves with the bus by calling
+auxiliary_driver_register(). The id_table contains the match_names of auxiliary
+devices that a driver can bind with.
+
+Example Usage
+=============
+
+Auxiliary devices are created and registered by a subsystem-level core device
+that needs to break up its functionality into smaller fragments. One way to
+extend the scope of an auxiliary_device is to encapsulate it within a domain-
+pecific structure defined by the parent device. This structure contains the
+auxiliary_device and any associated shared data/callbacks needed to establish
+the connection with the parent.
+
+An example is:
+
+.. code-block:: c
+
+ struct foo {
+ struct auxiliary_device auxdev;
+ void (*connect)(struct auxiliary_device *auxdev);
+ void (*disconnect)(struct auxiliary_device *auxdev);
+ void *data;
+ };
+
+The parent device then registers the auxiliary_device by calling
+auxiliary_device_init(), and then auxiliary_device_add(), with the pointer to
+the auxdev member of the above structure. The parent provides a name for the
+auxiliary_device that, combined with the parent's KBUILD_MODNAME, creates a
+match_name that is be used for matching and binding with a driver.
+
+Whenever an auxiliary_driver is registered, based on the match_name, the
+auxiliary_driver's probe() is invoked for the matching devices. The
+auxiliary_driver can also be encapsulated inside custom drivers that make the
+core device's functionality extensible by adding additional domain-specific ops
+as follows:
+
+.. code-block:: c
+
+ struct my_ops {
+ void (*send)(struct auxiliary_device *auxdev);
+ void (*receive)(struct auxiliary_device *auxdev);
+ };
+
+
+ struct my_driver {
+ struct auxiliary_driver auxiliary_drv;
+ const struct my_ops ops;
+ };
+
+An example of this type of usage is:
+
+.. code-block:: c
+
+ const struct auxiliary_device_id my_auxiliary_id_table[] = {
+ { .name = "foo_mod.foo_dev" },
+ { },
+ };
+
+ const struct my_ops my_custom_ops = {
+ .send = my_tx,
+ .receive = my_rx,
+ };
+
+ const struct my_driver my_drv = {
+ .auxiliary_drv = {
+ .name = "myauxiliarydrv",
+ .id_table = my_auxiliary_id_table,
+ .probe = my_probe,
+ .remove = my_remove,
+ .shutdown = my_shutdown,
+ },
+ .ops = my_custom_ops,
+ };
diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
index f357f3eb400c..86759a74b7f1 100644
--- a/Documentation/driver-api/index.rst
+++ b/Documentation/driver-api/index.rst
@@ -72,6 +72,7 @@ available subsections can be seen below.
thermal/index
fpga/index
acpi/index
+ auxiliary_bus
backlight/lp855x-driver.rst
connector
console
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 8d7001712062..040be48ce046 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -1,6 +1,9 @@
# SPDX-License-Identifier: GPL-2.0
menu "Generic Driver Options"
+config AUXILIARY_BUS
+ bool
+
config UEVENT_HELPER
bool "Support for uevent helper"
help
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 41369fc7004f..5e7bf9669a81 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -7,6 +7,7 @@ obj-y := component.o core.o bus.o dd.o syscore.o \
attribute_container.o transport_class.o \
topology.o container.o property.o cacheinfo.o \
swnode.o
+obj-$(CONFIG_AUXILIARY_BUS) += auxiliary.o
obj-$(CONFIG_DEVTMPFS) += devtmpfs.o
obj-y += power/
obj-$(CONFIG_ISA_BUS_API) += isa.o
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
new file mode 100644
index 000000000000..ef2af417438b
--- /dev/null
+++ b/drivers/base/auxiliary.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2019-2020 Intel Corporation
+ *
+ * Please see Documentation/driver-api/auxiliary_bus.rst for more information.
+ */
+
+#define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
+#include <linux/string.h>
+#include <linux/auxiliary_bus.h>
+
+static const struct auxiliary_device_id *auxiliary_match_id(const struct auxiliary_device_id *id,
+ const struct auxiliary_device *auxdev)
+{
+ for (; id->name[0]; id++) {
+ const char *p = strrchr(dev_name(&auxdev->dev), '.');
+ int match_size;
+
+ if (!p)
+ continue;
+ match_size = p - dev_name(&auxdev->dev);
+
+ /* use dev_name(&auxdev->dev) prefix before last '.' char to match to */
+ if (strlen(id->name) == match_size &&
+ !strncmp(dev_name(&auxdev->dev), id->name, match_size))
+ return id;
+ }
+ return NULL;
+}
+
+static int auxiliary_match(struct device *dev, struct device_driver *drv)
+{
+ struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
+ struct auxiliary_driver *auxdrv = to_auxiliary_drv(drv);
+
+ return !!auxiliary_match_id(auxdrv->id_table, auxdev);
+}
+
+static int auxiliary_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ const char *name, *p;
+
+ name = dev_name(dev);
+ p = strrchr(name, '.');
+
+ return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX, (int)(p - name),
+ name);
+}
+
+static const struct dev_pm_ops auxiliary_dev_pm_ops = {
+ SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_generic_suspend, pm_generic_resume)
+};
+
+static int auxiliary_bus_probe(struct device *dev)
+{
+ struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);
+ struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
+ int ret;
+
+ ret = dev_pm_domain_attach(dev, true);
+ if (ret) {
+ dev_warn(dev, "Failed to attach to PM Domain : %d\n", ret);
+ return ret;
+ }
+
+ ret = auxdrv->probe(auxdev, auxiliary_match_id(auxdrv->id_table, auxdev));
+ if (ret)
+ dev_pm_domain_detach(dev, true);
+
+ return ret;
+}
+
+static int auxiliary_bus_remove(struct device *dev)
+{
+ struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);
+ struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
+ int ret = 0;
+
+ if (auxdrv->remove)
+ ret = auxdrv->remove(auxdev);
+ dev_pm_domain_detach(dev, true);
+
+ return ret;
+}
+
+static void auxiliary_bus_shutdown(struct device *dev)
+{
+ struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);
+ struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
+
+ if (auxdrv->shutdown)
+ auxdrv->shutdown(auxdev);
+}
+
+static struct bus_type auxiliary_bus_type = {
+ .name = "auxiliary",
+ .probe = auxiliary_bus_probe,
+ .remove = auxiliary_bus_remove,
+ .shutdown = auxiliary_bus_shutdown,
+ .match = auxiliary_match,
+ .uevent = auxiliary_uevent,
+ .pm = &auxiliary_dev_pm_ops,
+};
+
+/**
+ * auxiliary_device_init - check auxiliary_device and initialize
+ * @auxdev: auxiliary device struct
+ *
+ * This is the first step in the two-step process to register an auxiliary_device.
+ *
+ * When this function returns an error code, then the device_initialize will *not* have
+ * been performed, and the caller will be responsible to free any memory allocated for the
+ * auxiliary_device in the error path directly.
+ *
+ * It returns 0 on success. On success, the device_initialize has been performed. After this
+ * point any error unwinding will need to include a call to auxiliary_device_uninit().
+ * In this post-initialize error scenario, a call to the device's .release callback will be
+ * triggered, and all memory clean-up is expected to be handled there.
+ */
+int auxiliary_device_init(struct auxiliary_device *auxdev)
+{
+ struct device *dev = &auxdev->dev;
+
+ if (!dev->parent) {
+ pr_err("auxiliary_device has a NULL dev->parent\n");
+ return -EINVAL;
+ }
+
+ if (!auxdev->name) {
+ pr_err("auxiliary_device has a NULL name\n");
+ return -EINVAL;
+ }
+
+ dev->bus = &auxiliary_bus_type;
+ device_initialize(&auxdev->dev);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(auxiliary_device_init);
+
+/**
+ * __auxiliary_device_add - add an auxiliary bus device
+ * @auxdev: auxiliary bus device to add to the bus
+ * @modname: name of the parent device's driver module
+ *
+ * This is the second step in the two-step process to register an auxiliary_device.
+ *
+ * This function must be called after a successful call to auxiliary_device_init(), which
+ * will perform the device_initialize. This means that if this returns an error code, then a
+ * call to auxiliary_device_uninit() must be performed so that the .release callback will
+ * be triggered to free the memory associated with the auxiliary_device.
+ *
+ * The expectation is that users will call the "auxiliary_device_add" macro so that the caller's
+ * KBUILD_MODNAME is automatically inserted for the modname parameter. Only if a user requires
+ * a custom name would this version be called directly.
+ */
+int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname)
+{
+ struct device *dev = &auxdev->dev;
+ int ret;
+
+ if (!modname) {
+ pr_err("auxiliary device modname is NULL\n");
+ return -EINVAL;
+ }
+
+ ret = dev_set_name(dev, "%s.%s.%d", modname, auxdev->name, auxdev->id);
+ if (ret) {
+ pr_err("auxiliary device dev_set_name failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = device_add(dev);
+ if (ret)
+ dev_err(dev, "adding auxiliary device failed!: %d\n", ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__auxiliary_device_add);
+
+/**
+ * auxiliary_find_device - auxiliary device iterator for locating a particular device.
+ * @start: Device to begin with
+ * @data: Data to pass to match function
+ * @match: Callback function to check device
+ *
+ * This function returns a reference to a device that is 'found'
+ * for later use, as determined by the @match callback.
+ *
+ * The callback should return 0 if the device doesn't match and non-zero
+ * if it does. If the callback returns non-zero, this function will
+ * return to the caller and not iterate over any more devices.
+ */
+struct auxiliary_device *
+auxiliary_find_device(struct device *start, const void *data,
+ int (*match)(struct device *dev, const void *data))
+{
+ struct device *dev;
+
+ dev = bus_find_device(&auxiliary_bus_type, start, data, match);
+ if (!dev)
+ return NULL;
+
+ return to_auxiliary_dev(dev);
+}
+EXPORT_SYMBOL_GPL(auxiliary_find_device);
+
+/**
+ * __auxiliary_driver_register - register a driver for auxiliary bus devices
+ * @auxdrv: auxiliary_driver structure
+ * @owner: owning module/driver
+ * @modname: KBUILD_MODNAME for parent driver
+ */
+int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner,
+ const char *modname)
+{
+ if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table))
+ return -EINVAL;
+
+ if (auxdrv->name)
+ auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname, auxdrv->name);
+ else
+ auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s", modname);
+ if (!auxdrv->driver.name)
+ return -ENOMEM;
+
+ auxdrv->driver.owner = owner;
+ auxdrv->driver.bus = &auxiliary_bus_type;
+ auxdrv->driver.mod_name = modname;
+
+ return driver_register(&auxdrv->driver);
+}
+EXPORT_SYMBOL_GPL(__auxiliary_driver_register);
+
+/**
+ * auxiliary_driver_unregister - unregister a driver
+ * @auxdrv: auxiliary_driver structure
+ */
+void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv)
+{
+ driver_unregister(&auxdrv->driver);
+ kfree(auxdrv->driver.name);
+}
+EXPORT_SYMBOL_GPL(auxiliary_driver_unregister);
+
+static int __init auxiliary_bus_init(void)
+{
+ return bus_register(&auxiliary_bus_type);
+}
+
+static void __exit auxiliary_bus_exit(void)
+{
+ bus_unregister(&auxiliary_bus_type);
+}
+
+module_init(auxiliary_bus_init);
+module_exit(auxiliary_bus_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Auxiliary Bus");
+MODULE_AUTHOR("David Ertman <david.m.ertman@intel.com>");
+MODULE_AUTHOR("Kiran Patil <kiran.patil@intel.com>");
diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h
new file mode 100644
index 000000000000..282fbf7bf9af
--- /dev/null
+++ b/include/linux/auxiliary_bus.h
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2020 Intel Corporation
+ *
+ * Please see Documentation/driver-api/auxiliary_bus.rst for more information.
+ */
+
+#ifndef _AUXILIARY_BUS_H_
+#define _AUXILIARY_BUS_H_
+
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+
+struct auxiliary_device {
+ struct device dev;
+ const char *name;
+ u32 id;
+};
+
+struct auxiliary_driver {
+ int (*probe)(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id);
+ int (*remove)(struct auxiliary_device *auxdev);
+ void (*shutdown)(struct auxiliary_device *auxdev);
+ int (*suspend)(struct auxiliary_device *auxdev, pm_message_t state);
+ int (*resume)(struct auxiliary_device *auxdev);
+ const char *name;
+ struct device_driver driver;
+ const struct auxiliary_device_id *id_table;
+};
+
+static inline struct auxiliary_device *to_auxiliary_dev(struct device *dev)
+{
+ return container_of(dev, struct auxiliary_device, dev);
+}
+
+static inline struct auxiliary_driver *to_auxiliary_drv(struct device_driver *drv)
+{
+ return container_of(drv, struct auxiliary_driver, driver);
+}
+
+int auxiliary_device_init(struct auxiliary_device *auxdev);
+int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname);
+#define auxiliary_device_add(auxdev) __auxiliary_device_add(auxdev, KBUILD_MODNAME)
+
+static inline void auxiliary_device_uninit(struct auxiliary_device *auxdev)
+{
+ put_device(&auxdev->dev);
+}
+
+static inline void auxiliary_device_delete(struct auxiliary_device *auxdev)
+{
+ device_del(&auxdev->dev);
+}
+
+int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner,
+ const char *modname);
+#define auxiliary_driver_register(auxdrv) \
+ __auxiliary_driver_register(auxdrv, THIS_MODULE, KBUILD_MODNAME)
+
+void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv);
+
+/**
+ * module_auxiliary_driver() - Helper macro for registering an auxiliary driver
+ * @__auxiliary_driver: auxiliary driver struct
+ *
+ * Helper macro for auxiliary drivers which do not do anything special in
+ * module init/exit. This eliminates a lot of boilerplate. Each module may only
+ * use this macro once, and calling it replaces module_init() and module_exit()
+ */
+#define module_auxiliary_driver(__auxiliary_driver) \
+ module_driver(__auxiliary_driver, auxiliary_driver_register, auxiliary_driver_unregister)
+
+struct auxiliary_device *
+auxiliary_find_device(struct device *start, const void *data,
+ int (*match)(struct device *dev, const void *data));
+
+#endif /* _AUXILIARY_BUS_H_ */
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 5b08a473cdba..c425290b21e2 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -838,4 +838,12 @@ struct mhi_device_id {
kernel_ulong_t driver_data;
};
+#define AUXILIARY_NAME_SIZE 32
+#define AUXILIARY_MODULE_PREFIX "auxiliary:"
+
+struct auxiliary_device_id {
+ char name[AUXILIARY_NAME_SIZE];
+ kernel_ulong_t driver_data;
+};
+
#endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index 27007c18e754..e377f52dbfa3 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -243,5 +243,8 @@ int main(void)
DEVID(mhi_device_id);
DEVID_FIELD(mhi_device_id, chan);
+ DEVID(auxiliary_device_id);
+ DEVID_FIELD(auxiliary_device_id, name);
+
return 0;
}
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 2417dd1dee33..fb4827027536 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1364,6 +1364,13 @@ static int do_mhi_entry(const char *filename, void *symval, char *alias)
{
DEF_FIELD_ADDR(symval, mhi_device_id, chan);
sprintf(alias, MHI_DEVICE_MODALIAS_FMT, *chan);
+ return 1;
+}
+
+static int do_auxiliary_entry(const char *filename, void *symval, char *alias)
+{
+ DEF_FIELD_ADDR(symval, auxiliary_device_id, name);
+ sprintf(alias, AUXILIARY_MODULE_PREFIX "%s", *name);
return 1;
}
@@ -1442,6 +1449,7 @@ static const struct devtable devtable[] = {
{"tee", SIZE_tee_client_device_id, do_tee_entry},
{"wmi", SIZE_wmi_device_id, do_wmi_entry},
{"mhi", SIZE_mhi_device_id, do_mhi_entry},
+ {"auxiliary", SIZE_auxiliary_device_id, do_auxiliary_entry},
};
/* Create MODULE_ALIAS() statements.
--
2.29.2

View File

@ -0,0 +1,54 @@
From a64e93a757edfad34955b79f1774d10e9dae955e Mon Sep 17 00:00:00 2001
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: Fri, 4 Dec 2020 12:43:47 +0100
Subject: [PATCH] driver core: auxiliary bus: move slab.h from include file
No need to include slab.h in include/linux/auxiliary_bus.h, as it is not
needed there. Move it to drivers/base/auxiliary.c instead.
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Ertman <david.m.ertman@intel.com>
Cc: Fred Oh <fred.oh@linux.intel.com>
Cc: Kiran Patil <kiran.patil@intel.com>
Cc: Leon Romanovsky <leonro@nvidia.com>
Cc: Martin Habets <mhabets@solarflare.com>
Cc: Parav Pandit <parav@mellanox.com>
Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Cc: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Cc: Shiraz Saleem <shiraz.saleem@intel.com>
Link: https://lore.kernel.org/r/X8og8xi3WkoYXet9@kroah.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 7bbb79ff5f7499e0c5d65987458410e8099207d8)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/base/auxiliary.c | 1 +
include/linux/auxiliary_bus.h | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index ef2af417438b..eca36d6284d0 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -9,6 +9,7 @@
#include <linux/device.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h
index 282fbf7bf9af..3580743d0e8d 100644
--- a/include/linux/auxiliary_bus.h
+++ b/include/linux/auxiliary_bus.h
@@ -10,7 +10,6 @@
#include <linux/device.h>
#include <linux/mod_devicetable.h>
-#include <linux/slab.h>
struct auxiliary_device {
struct device dev;
--
2.29.2

View File

@ -0,0 +1,79 @@
From 1eef241f79083237468a534e739ae053f2b7cfd5 Mon Sep 17 00:00:00 2001
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: Fri, 4 Dec 2020 12:44:07 +0100
Subject: [PATCH] driver core: auxiliary bus: make remove function return void
There's an effort to move the remove() callback in the driver core to
not return an int, as nothing can be done if this function fails. To
make that effort easier, make the aux bus remove function void to start
with so that no users have to be changed sometime in the future.
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Ertman <david.m.ertman@intel.com>
Cc: Fred Oh <fred.oh@linux.intel.com>
Cc: Kiran Patil <kiran.patil@intel.com>
Cc: Leon Romanovsky <leonro@nvidia.com>
Cc: Martin Habets <mhabets@solarflare.com>
Cc: Parav Pandit <parav@mellanox.com>
Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Cc: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Cc: Shiraz Saleem <shiraz.saleem@intel.com>
Link: https://lore.kernel.org/r/X8ohB1ks1NK7kPop@kroah.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 8142a46c50d2dd8160c42284e1044eed3bec0d18)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
Documentation/driver-api/auxiliary_bus.rst | 2 +-
drivers/base/auxiliary.c | 5 ++---
include/linux/auxiliary_bus.h | 2 +-
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/Documentation/driver-api/auxiliary_bus.rst b/Documentation/driver-api/auxiliary_bus.rst
index 5dd7804631ef..2312506b0674 100644
--- a/Documentation/driver-api/auxiliary_bus.rst
+++ b/Documentation/driver-api/auxiliary_bus.rst
@@ -150,7 +150,7 @@ and shutdown notifications using the standard conventions.
struct auxiliary_driver {
int (*probe)(struct auxiliary_device *,
const struct auxiliary_device_id *id);
- int (*remove)(struct auxiliary_device *);
+ void (*remove)(struct auxiliary_device *);
void (*shutdown)(struct auxiliary_device *);
int (*suspend)(struct auxiliary_device *, pm_message_t);
int (*resume)(struct auxiliary_device *);
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index eca36d6284d0..c44e85802b43 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -82,13 +82,12 @@ static int auxiliary_bus_remove(struct device *dev)
{
struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);
struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
- int ret = 0;
if (auxdrv->remove)
- ret = auxdrv->remove(auxdev);
+ auxdrv->remove(auxdev);
dev_pm_domain_detach(dev, true);
- return ret;
+ return 0;
}
static void auxiliary_bus_shutdown(struct device *dev)
diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h
index 3580743d0e8d..d67b17606210 100644
--- a/include/linux/auxiliary_bus.h
+++ b/include/linux/auxiliary_bus.h
@@ -19,7 +19,7 @@ struct auxiliary_device {
struct auxiliary_driver {
int (*probe)(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id);
- int (*remove)(struct auxiliary_device *auxdev);
+ void (*remove)(struct auxiliary_device *auxdev);
void (*shutdown)(struct auxiliary_device *auxdev);
int (*suspend)(struct auxiliary_device *auxdev, pm_message_t state);
int (*resume)(struct auxiliary_device *auxdev);
--
2.29.2

View File

@ -0,0 +1,166 @@
From 67b5e80aad2083d07dcbe0e36eb15e65217f373b Mon Sep 17 00:00:00 2001
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: Fri, 4 Dec 2020 12:49:28 +0100
Subject: [PATCH] driver core: auxiliary bus: minor coding style tweaks
For some reason, the original aux bus patch had some really long lines
in a few places, probably due to it being a very long-lived patch in
development by many different people. Fix that up so that the two files
all have the same length lines and function formatting styles.
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Ertman <david.m.ertman@intel.com>
Cc: Fred Oh <fred.oh@linux.intel.com>
Cc: Kiran Patil <kiran.patil@intel.com>
Cc: Leon Romanovsky <leonro@nvidia.com>
Cc: Martin Habets <mhabets@solarflare.com>
Cc: Parav Pandit <parav@mellanox.com>
Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Cc: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Cc: Shiraz Saleem <shiraz.saleem@intel.com>
Link: https://lore.kernel.org/r/X8oiSFTpYHw1xE/o@kroah.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 0d2bf11a6b3e275a526b8d42d8d4a3a6067cf953)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/base/auxiliary.c | 58 +++++++++++++++++++----------------
include/linux/auxiliary_bus.h | 6 ++--
2 files changed, 35 insertions(+), 29 deletions(-)
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index c44e85802b43..f303daadf843 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -50,8 +50,8 @@ static int auxiliary_uevent(struct device *dev, struct kobj_uevent_env *env)
name = dev_name(dev);
p = strrchr(name, '.');
- return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX, (int)(p - name),
- name);
+ return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX,
+ (int)(p - name), name);
}
static const struct dev_pm_ops auxiliary_dev_pm_ops = {
@@ -113,16 +113,18 @@ static struct bus_type auxiliary_bus_type = {
* auxiliary_device_init - check auxiliary_device and initialize
* @auxdev: auxiliary device struct
*
- * This is the first step in the two-step process to register an auxiliary_device.
+ * This is the first step in the two-step process to register an
+ * auxiliary_device.
*
- * When this function returns an error code, then the device_initialize will *not* have
- * been performed, and the caller will be responsible to free any memory allocated for the
- * auxiliary_device in the error path directly.
+ * When this function returns an error code, then the device_initialize will
+ * *not* have been performed, and the caller will be responsible to free any
+ * memory allocated for the auxiliary_device in the error path directly.
*
- * It returns 0 on success. On success, the device_initialize has been performed. After this
- * point any error unwinding will need to include a call to auxiliary_device_uninit().
- * In this post-initialize error scenario, a call to the device's .release callback will be
- * triggered, and all memory clean-up is expected to be handled there.
+ * It returns 0 on success. On success, the device_initialize has been
+ * performed. After this point any error unwinding will need to include a call
+ * to auxiliary_device_uninit(). In this post-initialize error scenario, a call
+ * to the device's .release callback will be triggered, and all memory clean-up
+ * is expected to be handled there.
*/
int auxiliary_device_init(struct auxiliary_device *auxdev)
{
@@ -149,16 +151,19 @@ EXPORT_SYMBOL_GPL(auxiliary_device_init);
* @auxdev: auxiliary bus device to add to the bus
* @modname: name of the parent device's driver module
*
- * This is the second step in the two-step process to register an auxiliary_device.
+ * This is the second step in the two-step process to register an
+ * auxiliary_device.
*
- * This function must be called after a successful call to auxiliary_device_init(), which
- * will perform the device_initialize. This means that if this returns an error code, then a
- * call to auxiliary_device_uninit() must be performed so that the .release callback will
- * be triggered to free the memory associated with the auxiliary_device.
+ * This function must be called after a successful call to
+ * auxiliary_device_init(), which will perform the device_initialize. This
+ * means that if this returns an error code, then a call to
+ * auxiliary_device_uninit() must be performed so that the .release callback
+ * will be triggered to free the memory associated with the auxiliary_device.
*
- * The expectation is that users will call the "auxiliary_device_add" macro so that the caller's
- * KBUILD_MODNAME is automatically inserted for the modname parameter. Only if a user requires
- * a custom name would this version be called directly.
+ * The expectation is that users will call the "auxiliary_device_add" macro so
+ * that the caller's KBUILD_MODNAME is automatically inserted for the modname
+ * parameter. Only if a user requires a custom name would this version be
+ * called directly.
*/
int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname)
{
@@ -166,13 +171,13 @@ int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname)
int ret;
if (!modname) {
- pr_err("auxiliary device modname is NULL\n");
+ dev_err(dev, "auxiliary device modname is NULL\n");
return -EINVAL;
}
ret = dev_set_name(dev, "%s.%s.%d", modname, auxdev->name, auxdev->id);
if (ret) {
- pr_err("auxiliary device dev_set_name failed: %d\n", ret);
+ dev_err(dev, "auxiliary device dev_set_name failed: %d\n", ret);
return ret;
}
@@ -197,9 +202,9 @@ EXPORT_SYMBOL_GPL(__auxiliary_device_add);
* if it does. If the callback returns non-zero, this function will
* return to the caller and not iterate over any more devices.
*/
-struct auxiliary_device *
-auxiliary_find_device(struct device *start, const void *data,
- int (*match)(struct device *dev, const void *data))
+struct auxiliary_device *auxiliary_find_device(struct device *start,
+ const void *data,
+ int (*match)(struct device *dev, const void *data))
{
struct device *dev;
@@ -217,14 +222,15 @@ EXPORT_SYMBOL_GPL(auxiliary_find_device);
* @owner: owning module/driver
* @modname: KBUILD_MODNAME for parent driver
*/
-int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner,
- const char *modname)
+int __auxiliary_driver_register(struct auxiliary_driver *auxdrv,
+ struct module *owner, const char *modname)
{
if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table))
return -EINVAL;
if (auxdrv->name)
- auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname, auxdrv->name);
+ auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname,
+ auxdrv->name);
else
auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s", modname);
if (!auxdrv->driver.name)
diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h
index d67b17606210..fc51d45f106b 100644
--- a/include/linux/auxiliary_bus.h
+++ b/include/linux/auxiliary_bus.h
@@ -70,8 +70,8 @@ void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv);
#define module_auxiliary_driver(__auxiliary_driver) \
module_driver(__auxiliary_driver, auxiliary_driver_register, auxiliary_driver_unregister)
-struct auxiliary_device *
-auxiliary_find_device(struct device *start, const void *data,
- int (*match)(struct device *dev, const void *data));
+struct auxiliary_device *auxiliary_find_device(struct device *start,
+ const void *data,
+ int (*match)(struct device *dev, const void *data));
#endif /* _AUXILIARY_BUS_H_ */
--
2.29.2

View File

@ -0,0 +1,49 @@
From 7f4d45ef5bfe6dd025b1f7c736d198b9a208cdef Mon Sep 17 00:00:00 2001
From: Dave Jiang <dave.jiang@intel.com>
Date: Fri, 4 Dec 2020 09:46:49 -0700
Subject: [PATCH] driver core: auxiliary bus: Fix auxiliary bus shutdown null
auxdrv ptr
If the probe of the auxdrv failed, the device->driver is set to NULL.
During kernel shutdown, the bus shutdown will call auxdrv->shutdown and
cause an invalid ptr dereference. Add check to make sure device->driver is
not NULL before we proceed.
Fixes: 7de3697e9cbd ("Add auxiliary bus support")
Cc: Dave Ertman <david.m.ertman@intel.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Link: https://lore.kernel.org/r/160710040926.1889434.8840329810698403478.stgit@djiang5-desk3.ch.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 784b2c48ac12dcee27db001fb1a3c58c39380cb6)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/base/auxiliary.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index f303daadf843..8336535f1e11 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -92,10 +92,15 @@ static int auxiliary_bus_remove(struct device *dev)
static void auxiliary_bus_shutdown(struct device *dev)
{
- struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);
- struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
+ struct auxiliary_driver *auxdrv = NULL;
+ struct auxiliary_device *auxdev;
+
+ if (dev->driver) {
+ auxdrv = to_auxiliary_drv(dev->driver);
+ auxdev = to_auxiliary_dev(dev);
+ }
- if (auxdrv->shutdown)
+ if (auxdrv && auxdrv->shutdown)
auxdrv->shutdown(auxdev);
}
--
2.29.2

View File

@ -0,0 +1,146 @@
From 87f05137d98572c5926bbc6949ecc6616bd90057 Mon Sep 17 00:00:00 2001
From: Dave Jiang <dave.jiang@intel.com>
Date: Wed, 10 Feb 2021 13:16:11 -0700
Subject: [PATCH] driver core: auxiliary bus: Fix calling stage for auxiliary
bus init
When the auxiliary device code is built into the kernel, it can be executed
before the auxiliary bus is registered. This causes bus->p to be not
allocated and triggers a NULL pointer dereference when the auxiliary bus
device gets added with bus_add_device(). Call the auxiliary_bus_init()
under driver_init() so the bus is initialized before devices.
Below is the kernel splat for the bug:
[ 1.948215] BUG: kernel NULL pointer dereference, address: 0000000000000060
[ 1.950670] #PF: supervisor read access in kernel mode
[ 1.950670] #PF: error_code(0x0000) - not-present page
[ 1.950670] PGD 0
[ 1.950670] Oops: 0000 1 SMP NOPTI
[ 1.950670] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.10.0-intel-nextsvmtest+ #2205
[ 1.950670] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[ 1.950670] RIP: 0010:bus_add_device+0x64/0x140
[ 1.950670] Code: 00 49 8b 75 20 48 89 df e8 59 a1 ff ff 41 89 c4 85 c0 75 7b 48 8b 53 50 48 85 d2 75 03 48 8b 13 49 8b 85 a0 00 00 00 48 89 de <48> 8
78 60 48 83 c7 18 e8 ef d9 a9 ff 41 89 c4 85 c0 75 45 48 8b
[ 1.950670] RSP: 0000:ff46032ac001baf8 EFLAGS: 00010246
[ 1.950670] RAX: 0000000000000000 RBX: ff4597f7414aa680 RCX: 0000000000000000
[ 1.950670] RDX: ff4597f74142bbc0 RSI: ff4597f7414aa680 RDI: ff4597f7414aa680
[ 1.950670] RBP: ff46032ac001bb10 R08: 0000000000000044 R09: 0000000000000228
[ 1.950670] R10: ff4597f741141b30 R11: ff4597f740182a90 R12: 0000000000000000
[ 1.950670] R13: ffffffffa5e936c0 R14: 0000000000000000 R15: 0000000000000000
[ 1.950670] FS: 0000000000000000(0000) GS:ff4597f7bba00000(0000) knlGS:0000000000000000
[ 1.950670] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1.950670] CR2: 0000000000000060 CR3: 000000002140c001 CR4: 0000000000f71ef0
[ 1.950670] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 1.950670] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400
[ 1.950670] PKRU: 55555554
[ 1.950670] Call Trace:
[ 1.950670] device_add+0x3ee/0x850
[ 1.950670] __auxiliary_device_add+0x47/0x60
[ 1.950670] idxd_pci_probe+0xf77/0x1180
[ 1.950670] local_pci_probe+0x4a/0x90
[ 1.950670] pci_device_probe+0xff/0x1b0
[ 1.950670] really_probe+0x1cf/0x440
[ 1.950670] ? rdinit_setup+0x31/0x31
[ 1.950670] driver_probe_device+0xe8/0x150
[ 1.950670] device_driver_attach+0x58/0x60
[ 1.950670] __driver_attach+0x8f/0x150
[ 1.950670] ? device_driver_attach+0x60/0x60
[ 1.950670] ? device_driver_attach+0x60/0x60
[ 1.950670] bus_for_each_dev+0x79/0xc0
[ 1.950670] ? kmem_cache_alloc_trace+0x323/0x430
[ 1.950670] driver_attach+0x1e/0x20
[ 1.950670] bus_add_driver+0x154/0x1f0
[ 1.950670] driver_register+0x70/0xc0
[ 1.950670] __pci_register_driver+0x54/0x60
[ 1.950670] idxd_init_module+0xe2/0xfc
[ 1.950670] ? idma64_platform_driver_init+0x19/0x19
[ 1.950670] do_one_initcall+0x4a/0x1e0
[ 1.950670] kernel_init_freeable+0x1fc/0x25c
[ 1.950670] ? rest_init+0xba/0xba
[ 1.950670] kernel_init+0xe/0x116
[ 1.950670] ret_from_fork+0x1f/0x30
[ 1.950670] Modules linked in:
[ 1.950670] CR2: 0000000000000060
[ 1.950670] --[ end trace cd7d1b226d3ca901 ]--
Fixes: 7de3697e9cbd ("Add auxiliary bus support")
Reported-by: Jacob Pan <jacob.jun.pan@intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Acked-by: Dave Ertman <david.m.ertman@intel.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/20210210201611.1611074-1-dave.jiang@intel.com
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 471b12c43f376d5203dbff0e91316eea11f6f4df)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/base/auxiliary.c | 13 +++----------
drivers/base/base.h | 5 +++++
drivers/base/init.c | 1 +
3 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index 8336535f1e11..d8b314e7d0fd 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -15,6 +15,7 @@
#include <linux/pm_runtime.h>
#include <linux/string.h>
#include <linux/auxiliary_bus.h>
+#include "base.h"
static const struct auxiliary_device_id *auxiliary_match_id(const struct auxiliary_device_id *id,
const struct auxiliary_device *auxdev)
@@ -260,19 +261,11 @@ void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv)
}
EXPORT_SYMBOL_GPL(auxiliary_driver_unregister);
-static int __init auxiliary_bus_init(void)
+void __init auxiliary_bus_init(void)
{
- return bus_register(&auxiliary_bus_type);
+ WARN_ON(bus_register(&auxiliary_bus_type));
}
-static void __exit auxiliary_bus_exit(void)
-{
- bus_unregister(&auxiliary_bus_type);
-}
-
-module_init(auxiliary_bus_init);
-module_exit(auxiliary_bus_exit);
-
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Auxiliary Bus");
MODULE_AUTHOR("David Ertman <david.m.ertman@intel.com>");
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 91cfb8405abd..7d97447460fa 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -119,6 +119,11 @@ static inline int hypervisor_init(void) { return 0; }
extern int platform_bus_init(void);
extern void cpu_dev_init(void);
extern void container_dev_init(void);
+#ifdef CONFIG_AUXILIARY_BUS
+extern void auxiliary_bus_init(void);
+#else
+static inline void auxiliary_bus_init(void) { }
+#endif
struct kobject *virtual_device_parent(struct device *dev);
diff --git a/drivers/base/init.c b/drivers/base/init.c
index 908e6520e804..a9f57c22fb9e 100644
--- a/drivers/base/init.c
+++ b/drivers/base/init.c
@@ -32,6 +32,7 @@ void __init driver_init(void)
*/
of_core_init();
platform_bus_init();
+ auxiliary_bus_init();
cpu_dev_init();
memory_dev_init();
container_dev_init();
--
2.29.2

View File

@ -0,0 +1,35 @@
From bcfe18a2fd6d45f14ae60c742a7661a64e46305e Mon Sep 17 00:00:00 2001
From: Dave Jiang <dave.jiang@intel.com>
Date: Thu, 11 Feb 2021 13:21:29 -0700
Subject: [PATCH] driver core: auxiliary bus: Remove unneeded module bits
Remove module bits in the auxiliary bus code since the auxiliary bus
cannot be built as a module and the relevant code is not needed.
Cc: Dave Ertman <david.m.ertman@intel.com>
Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/161307488980.1896017.15627190714413338196.stgit@djiang5-desk3.ch.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit bbf44abeeabfe05a124535e6c3a9fd7d682d42bf)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/base/auxiliary.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index d8b314e7d0fd..adc199dfba3c 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -265,8 +265,3 @@ void __init auxiliary_bus_init(void)
{
WARN_ON(bus_register(&auxiliary_bus_type));
}
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Auxiliary Bus");
-MODULE_AUTHOR("David Ertman <david.m.ertman@intel.com>");
-MODULE_AUTHOR("Kiran Patil <kiran.patil@intel.com>");
--
2.29.2

View File

@ -0,0 +1,51 @@
From 09b57232d358202d79e2133d523a664906e9759c Mon Sep 17 00:00:00 2001
From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Date: Tue, 13 Jul 2021 12:34:38 +0300
Subject: [PATCH] driver core: auxiliary bus: Fix memory leak when
driver_register() fail
If driver_register() returns with error we need to free the memory
allocated for auxdrv->driver.name before returning from
__auxiliary_driver_register()
Fixes: 7de3697e9cbd4 ("Add auxiliary bus support")
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20210713093438.3173-1-peter.ujfalusi@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 4afa0c22eed33cfe0c590742387f0d16f32412f3)
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/base/auxiliary.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index adc199dfba3c..6a30264ab2ba 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -231,6 +231,8 @@ EXPORT_SYMBOL_GPL(auxiliary_find_device);
int __auxiliary_driver_register(struct auxiliary_driver *auxdrv,
struct module *owner, const char *modname)
{
+ int ret;
+
if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table))
return -EINVAL;
@@ -246,7 +248,11 @@ int __auxiliary_driver_register(struct auxiliary_driver *auxdrv,
auxdrv->driver.bus = &auxiliary_bus_type;
auxdrv->driver.mod_name = modname;
- return driver_register(&auxdrv->driver);
+ ret = driver_register(&auxdrv->driver);
+ if (ret)
+ kfree(auxdrv->driver.name);
+
+ return ret;
}
EXPORT_SYMBOL_GPL(__auxiliary_driver_register);
--
2.29.2

View File

@ -0,0 +1,38 @@
From b1d1297d44033ae1d756838d6e06f04d52d1ceb6 Mon Sep 17 00:00:00 2001
From: "M. Vefa Bicakci" <vefa.bicakci@windriver.com>
Date: Thu, 17 Feb 2022 14:17:58 -0500
Subject: [PATCH] driver core: auxiliary bus: Enable by default
This commit enables CONFIG_AUXILIARY_BUS by default. This is necessary,
because StarlingX does not enable any kernel modules that 'select'
CONFIG_AUXILIARY_BUS, which causes the kernel's build system to
automatically disable this option.
However, StarlingX has out-of-tree users of this functionality (such as
the 'ice' and 'mlnx-ofa_kernel' out-of-tree kernel driver packages),
hence the need for this change. Prior to this commit, the aforementioned
out-of-tree kernel drivers would use their embedded/bundled copy of the
same functionality, which would cause kernel symbol conflicts at
run-time when users attempted to load both ice and mlnx-ofa_kernel
drivers.
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
---
drivers/base/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 040be48ce046..a18ec49b9dac 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -3,6 +3,7 @@ menu "Generic Driver Options"
config AUXILIARY_BUS
bool
+ default y
config UEVENT_HELPER
bool "Support for uevent helper"
--
2.29.2

View File

@ -9,3 +9,20 @@
0009-tpm-ignore-burstcount-to-improve-tpm_tis-send-perfor.patch
0010-bpf-cgroups-Fix-cgroup-v2-fallback-on-v1-v2-mixed-mo.patch
0011-scsi-smartpqi-Enable-sas_address-sysfs-for-SATA-dev.patch
0012-workqueue-Affine-rescuer-threads-and-unbound-wqs.patch
0013-rcu-Mark-accesses-to-rcu_state.n_force_qs.patch
0014-rcu-Tighten-rcu_advance_cbs_nowake-checks.patch
0015-Revert-scsi-sd-Inline-sd_probe_part2.patch
0016-Revert-commit-f049cf1a7b.patch
0017-genirq-Export-affinity-setter-for-modules.patch
0018-genirq-Provide-new-interfaces-for-affinity-hints.patch
0019-ixgbe-Use-irq_update_affinity_hint.patch
0020-Add-auxiliary-bus-support.patch
0021-driver-core-auxiliary-bus-move-slab.h-from-include-f.patch
0022-driver-core-auxiliary-bus-make-remove-function-retur.patch
0023-driver-core-auxiliary-bus-minor-coding-style-tweaks.patch
0024-driver-core-auxiliary-bus-Fix-auxiliary-bus-shutdown.patch
0025-driver-core-auxiliary-bus-Fix-calling-stage-for-auxi.patch
0026-driver-core-auxiliary-bus-Remove-unneeded-module-bit.patch
0027-driver-core-auxiliary-bus-Fix-memory-leak-when-drive.patch
0028-driver-core-auxiliary-bus-Enable-by-default.patch