Skip to content

Commit fa309f4

Browse files
committed
Add Linux 5.5 compat patch
Upstream fix: openzfs/zfs#10072
1 parent 58fcba6 commit fa309f4

File tree

5 files changed

+289
-5
lines changed

5 files changed

+289
-5
lines changed

src/kernels/dkms.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ mode_name="dkms"
33
mode_desc="Select and use the dkms packages"
44

55
# version
6-
pkgrel="1"
6+
pkgrel="2"
77

88
# Version for GIT packages
99
pkgrel_git="1"

src/zfs-dkms/PKGBUILD.sh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ pkgrel=${zfs_pkgrel}
1010
makedepends=(${zfs_makedepends})
1111
arch=("x86_64")
1212
url="https://zfsonlinux.org/"
13-
source=("${zfs_src_target}")
14-
sha256sums=("${zfs_src_hash}")
13+
source=("${zfs_src_target}"
14+
"linux-5.5-compat-blkg_tryget.patch")
15+
sha256sums=("${zfs_src_hash}"
16+
"daae58460243c45c2c7505b1d88dcb299ea7d92bcf3f41d2d30bc213000bb1da")
1517
license=("CDDL")
1618
depends=("${zfs_utils_pkgname}" "lsb-release" "dkms")
1719
provides=("zfs" "zfs-headers" "spl" "spl-headers")
@@ -38,4 +40,8 @@ package() {
3840
3941
EOF
4042

43+
if [[ ! ${archzfs_package_group} =~ -git$ ]] && [[ ! ${archzfs_package_group} =~ -rc$ ]]; then
44+
sed -E -i "/^build()/i prepare() {\n cd \"${zfs_workdir}\"\n patch -Np1 -i \${srcdir}/linux-5.5-compat-blkg_tryget.patch\n}" ${zfs_dkms_pkgbuild_path}/PKGBUILD
45+
fi
46+
4147
pkgbuild_cleanup "${zfs_dkms_pkgbuild_path}/PKGBUILD"
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
From 2fcab8795c7c493845bfa277d44bc443802000b8 Mon Sep 17 00:00:00 2001
2+
From: Brian Behlendorf <[email protected]>
3+
Date: Fri, 28 Feb 2020 08:58:39 -0800
4+
Subject: [PATCH] Linux 5.5 compat: blkg_tryget()
5+
6+
Commit https://github.com/torvalds/linux/commit/9e8d42a0f accidentally
7+
converted the static inline function blkg_tryget() to GPL-only for
8+
kernels built with CONFIG_PREEMPT_RCU=y and CONFIG_BLK_CGROUP=y.
9+
10+
Resolve the build issue by providing our own equivalent functionality
11+
when needed which uses rcu_read_lock_sched() internally as before.
12+
13+
Reviewed-by: Tony Hutter <[email protected]>
14+
Signed-off-by: Brian Behlendorf <[email protected]>
15+
Closes #9745
16+
Closes #10072
17+
---
18+
config/kernel-blkg-tryget.m4 | 37 ++++++++++++++++++++++++++++++++++++
19+
config/kernel.m4 | 2 ++
20+
module/zfs/vdev_disk.c | 32 ++++++++++++++++++++++++++++++-
21+
3 files changed, 70 insertions(+), 1 deletion(-)
22+
create mode 100644 config/kernel-blkg-tryget.m4
23+
24+
diff --git a/config/kernel-blkg-tryget.m4 b/config/kernel-blkg-tryget.m4
25+
new file mode 100644
26+
index 00000000000..fb831ca3b3e
27+
--- /dev/null
28+
+++ b/config/kernel-blkg-tryget.m4
29+
@@ -0,0 +1,37 @@
30+
+dnl #
31+
+dnl # Linux 5.5 API,
32+
+dnl #
33+
+dnl # The Linux 5.5 kernel updated percpu_ref_tryget() which is inlined by
34+
+dnl # blkg_tryget() to use rcu_read_lock() instead of rcu_read_lock_sched().
35+
+dnl # As a side effect the function was converted to GPL-only.
36+
+dnl #
37+
+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKG_TRYGET], [
38+
+ ZFS_LINUX_TEST_SRC([blkg_tryget], [
39+
+ #include <linux/blk-cgroup.h>
40+
+ #include <linux/bio.h>
41+
+ #include <linux/fs.h>
42+
+ ],[
43+
+ struct blkcg_gq blkg __attribute__ ((unused));
44+
+ bool rc __attribute__ ((unused));
45+
+ rc = blkg_tryget(&blkg);
46+
+ ], [], [$ZFS_META_LICENSE])
47+
+])
48+
+
49+
+AC_DEFUN([ZFS_AC_KERNEL_BLKG_TRYGET], [
50+
+ AC_MSG_CHECKING([whether blkg_tryget() is available])
51+
+ ZFS_LINUX_TEST_RESULT([blkg_tryget], [
52+
+ AC_MSG_RESULT(yes)
53+
+ AC_DEFINE(HAVE_BLKG_TRYGET, 1, [blkg_tryget() is available])
54+
+
55+
+ AC_MSG_CHECKING([whether blkg_tryget() is GPL-only])
56+
+ ZFS_LINUX_TEST_RESULT([blkg_tryget_license], [
57+
+ AC_MSG_RESULT(no)
58+
+ ],[
59+
+ AC_MSG_RESULT(yes)
60+
+ AC_DEFINE(HAVE_BLKG_TRYGET_GPL_ONLY, 1,
61+
+ [blkg_tryget() GPL-only])
62+
+ ])
63+
+ ],[
64+
+ AC_MSG_RESULT(no)
65+
+ ])
66+
+])
67+
diff --git a/config/kernel.m4 b/config/kernel.m4
68+
index dce619729d4..bea6f9b1bbf 100644
69+
--- a/config/kernel.m4
70+
+++ b/config/kernel.m4
71+
@@ -70,6 +70,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
72+
ZFS_AC_KERNEL_SRC_BIO_BI_STATUS
73+
ZFS_AC_KERNEL_SRC_BIO_RW_BARRIER
74+
ZFS_AC_KERNEL_SRC_BIO_RW_DISCARD
75+
+ ZFS_AC_KERNEL_SRC_BLKG_TRYGET
76+
ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI
77+
ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD
78+
ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE
79+
@@ -186,6 +187,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
80+
ZFS_AC_KERNEL_BIO_BI_STATUS
81+
ZFS_AC_KERNEL_BIO_RW_BARRIER
82+
ZFS_AC_KERNEL_BIO_RW_DISCARD
83+
+ ZFS_AC_KERNEL_BLKG_TRYGET
84+
ZFS_AC_KERNEL_BLK_QUEUE_BDI
85+
ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
86+
ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
87+
diff --git a/module/zfs/vdev_disk.c b/module/zfs/vdev_disk.c
88+
index 661f0f1b727..8544bb8ffb6 100644
89+
--- a/module/zfs/vdev_disk.c
90+
+++ b/module/zfs/vdev_disk.c
91+
@@ -473,6 +473,36 @@ vdev_submit_bio_impl(struct bio *bio)
92+
93+
#ifdef HAVE_BIO_SET_DEV
94+
#if defined(CONFIG_BLK_CGROUP) && defined(HAVE_BIO_SET_DEV_GPL_ONLY)
95+
+/*
96+
+ * The Linux 5.5 kernel updated percpu_ref_tryget() which is inlined by
97+
+ * blkg_tryget() to use rcu_read_lock() instead of rcu_read_lock_sched().
98+
+ * As a side effect the function was converted to GPL-only. Define our
99+
+ * own version when needed which uses rcu_read_lock_sched().
100+
+ */
101+
+#if defined(HAVE_BLKG_TRYGET_GPL_ONLY)
102+
+static inline bool
103+
+vdev_blkg_tryget(struct blkcg_gq *blkg)
104+
+{
105+
+ struct percpu_ref *ref = &blkg->refcnt;
106+
+ unsigned long __percpu *count;
107+
+ bool rc;
108+
+
109+
+ rcu_read_lock_sched();
110+
+
111+
+ if (__ref_is_percpu(ref, &count)) {
112+
+ this_cpu_inc(*count);
113+
+ rc = true;
114+
+ } else {
115+
+ rc = atomic_long_inc_not_zero(&ref->count);
116+
+ }
117+
+
118+
+ rcu_read_unlock_sched();
119+
+
120+
+ return (rc);
121+
+}
122+
+#elif defined(HAVE_BLKG_TRYGET)
123+
+#define vdev_blkg_tryget(bg) blkg_tryget(bg)
124+
+#endif
125+
/*
126+
* The Linux 5.0 kernel updated the bio_set_dev() macro so it calls the
127+
* GPL-only bio_associate_blkg() symbol thus inadvertently converting
128+
@@ -487,7 +517,7 @@ vdev_bio_associate_blkg(struct bio *bio)
129+
ASSERT3P(q, !=, NULL);
130+
ASSERT3P(bio->bi_blkg, ==, NULL);
131+
132+
- if (q->root_blkg && blkg_tryget(q->root_blkg))
133+
+ if (q->root_blkg && vdev_blkg_tryget(q->root_blkg))
134+
bio->bi_blkg = q->root_blkg;
135+
}
136+
#define bio_associate_blkg vdev_bio_associate_blkg

src/zfs/PKGBUILD.sh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ pkgrel=${zfs_pkgrel}
1515
makedepends=(${linux_headers_depends} ${zfs_makedepends})
1616
arch=("x86_64")
1717
url="https://zfsonlinux.org/"
18-
source=("${zfs_src_target}")
19-
sha256sums=("${zfs_src_hash}")
18+
source=("${zfs_src_target}"
19+
"linux-5.5-compat-blkg_tryget.patch")
20+
sha256sums=("${zfs_src_hash}"
21+
"daae58460243c45c2c7505b1d88dcb299ea7d92bcf3f41d2d30bc213000bb1da")
2022
license=("CDDL")
2123
depends=("kmod" "${zfs_utils_pkgname}" ${linux_depends})
2224
@@ -63,4 +65,8 @@ package_${zfs_pkgname}-headers() {
6365
6466
EOF
6567

68+
if [[ ! ${archzfs_package_group} =~ -git$ ]] && [[ ! ${archzfs_package_group} =~ -rc$ ]]; then
69+
sed -E -i "/^build()/i prepare() {\n cd \"${zfs_workdir}\"\n patch -Np1 -i \${srcdir}/linux-5.5-compat-blkg_tryget.patch\n}" ${zfs_dkms_pkgbuild_path}/PKGBUILD
70+
fi
71+
6672
pkgbuild_cleanup "${zfs_pkgbuild_path}/PKGBUILD"
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
From 2fcab8795c7c493845bfa277d44bc443802000b8 Mon Sep 17 00:00:00 2001
2+
From: Brian Behlendorf <[email protected]>
3+
Date: Fri, 28 Feb 2020 08:58:39 -0800
4+
Subject: [PATCH] Linux 5.5 compat: blkg_tryget()
5+
6+
Commit https://github.com/torvalds/linux/commit/9e8d42a0f accidentally
7+
converted the static inline function blkg_tryget() to GPL-only for
8+
kernels built with CONFIG_PREEMPT_RCU=y and CONFIG_BLK_CGROUP=y.
9+
10+
Resolve the build issue by providing our own equivalent functionality
11+
when needed which uses rcu_read_lock_sched() internally as before.
12+
13+
Reviewed-by: Tony Hutter <[email protected]>
14+
Signed-off-by: Brian Behlendorf <[email protected]>
15+
Closes #9745
16+
Closes #10072
17+
---
18+
config/kernel-blkg-tryget.m4 | 37 ++++++++++++++++++++++++++++++++++++
19+
config/kernel.m4 | 2 ++
20+
module/zfs/vdev_disk.c | 32 ++++++++++++++++++++++++++++++-
21+
3 files changed, 70 insertions(+), 1 deletion(-)
22+
create mode 100644 config/kernel-blkg-tryget.m4
23+
24+
diff --git a/config/kernel-blkg-tryget.m4 b/config/kernel-blkg-tryget.m4
25+
new file mode 100644
26+
index 00000000000..fb831ca3b3e
27+
--- /dev/null
28+
+++ b/config/kernel-blkg-tryget.m4
29+
@@ -0,0 +1,37 @@
30+
+dnl #
31+
+dnl # Linux 5.5 API,
32+
+dnl #
33+
+dnl # The Linux 5.5 kernel updated percpu_ref_tryget() which is inlined by
34+
+dnl # blkg_tryget() to use rcu_read_lock() instead of rcu_read_lock_sched().
35+
+dnl # As a side effect the function was converted to GPL-only.
36+
+dnl #
37+
+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKG_TRYGET], [
38+
+ ZFS_LINUX_TEST_SRC([blkg_tryget], [
39+
+ #include <linux/blk-cgroup.h>
40+
+ #include <linux/bio.h>
41+
+ #include <linux/fs.h>
42+
+ ],[
43+
+ struct blkcg_gq blkg __attribute__ ((unused));
44+
+ bool rc __attribute__ ((unused));
45+
+ rc = blkg_tryget(&blkg);
46+
+ ], [], [$ZFS_META_LICENSE])
47+
+])
48+
+
49+
+AC_DEFUN([ZFS_AC_KERNEL_BLKG_TRYGET], [
50+
+ AC_MSG_CHECKING([whether blkg_tryget() is available])
51+
+ ZFS_LINUX_TEST_RESULT([blkg_tryget], [
52+
+ AC_MSG_RESULT(yes)
53+
+ AC_DEFINE(HAVE_BLKG_TRYGET, 1, [blkg_tryget() is available])
54+
+
55+
+ AC_MSG_CHECKING([whether blkg_tryget() is GPL-only])
56+
+ ZFS_LINUX_TEST_RESULT([blkg_tryget_license], [
57+
+ AC_MSG_RESULT(no)
58+
+ ],[
59+
+ AC_MSG_RESULT(yes)
60+
+ AC_DEFINE(HAVE_BLKG_TRYGET_GPL_ONLY, 1,
61+
+ [blkg_tryget() GPL-only])
62+
+ ])
63+
+ ],[
64+
+ AC_MSG_RESULT(no)
65+
+ ])
66+
+])
67+
diff --git a/config/kernel.m4 b/config/kernel.m4
68+
index dce619729d4..bea6f9b1bbf 100644
69+
--- a/config/kernel.m4
70+
+++ b/config/kernel.m4
71+
@@ -70,6 +70,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
72+
ZFS_AC_KERNEL_SRC_BIO_BI_STATUS
73+
ZFS_AC_KERNEL_SRC_BIO_RW_BARRIER
74+
ZFS_AC_KERNEL_SRC_BIO_RW_DISCARD
75+
+ ZFS_AC_KERNEL_SRC_BLKG_TRYGET
76+
ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI
77+
ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD
78+
ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE
79+
@@ -186,6 +187,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
80+
ZFS_AC_KERNEL_BIO_BI_STATUS
81+
ZFS_AC_KERNEL_BIO_RW_BARRIER
82+
ZFS_AC_KERNEL_BIO_RW_DISCARD
83+
+ ZFS_AC_KERNEL_BLKG_TRYGET
84+
ZFS_AC_KERNEL_BLK_QUEUE_BDI
85+
ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
86+
ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
87+
diff --git a/module/zfs/vdev_disk.c b/module/zfs/vdev_disk.c
88+
index 661f0f1b727..8544bb8ffb6 100644
89+
--- a/module/zfs/vdev_disk.c
90+
+++ b/module/zfs/vdev_disk.c
91+
@@ -473,6 +473,36 @@ vdev_submit_bio_impl(struct bio *bio)
92+
93+
#ifdef HAVE_BIO_SET_DEV
94+
#if defined(CONFIG_BLK_CGROUP) && defined(HAVE_BIO_SET_DEV_GPL_ONLY)
95+
+/*
96+
+ * The Linux 5.5 kernel updated percpu_ref_tryget() which is inlined by
97+
+ * blkg_tryget() to use rcu_read_lock() instead of rcu_read_lock_sched().
98+
+ * As a side effect the function was converted to GPL-only. Define our
99+
+ * own version when needed which uses rcu_read_lock_sched().
100+
+ */
101+
+#if defined(HAVE_BLKG_TRYGET_GPL_ONLY)
102+
+static inline bool
103+
+vdev_blkg_tryget(struct blkcg_gq *blkg)
104+
+{
105+
+ struct percpu_ref *ref = &blkg->refcnt;
106+
+ unsigned long __percpu *count;
107+
+ bool rc;
108+
+
109+
+ rcu_read_lock_sched();
110+
+
111+
+ if (__ref_is_percpu(ref, &count)) {
112+
+ this_cpu_inc(*count);
113+
+ rc = true;
114+
+ } else {
115+
+ rc = atomic_long_inc_not_zero(&ref->count);
116+
+ }
117+
+
118+
+ rcu_read_unlock_sched();
119+
+
120+
+ return (rc);
121+
+}
122+
+#elif defined(HAVE_BLKG_TRYGET)
123+
+#define vdev_blkg_tryget(bg) blkg_tryget(bg)
124+
+#endif
125+
/*
126+
* The Linux 5.0 kernel updated the bio_set_dev() macro so it calls the
127+
* GPL-only bio_associate_blkg() symbol thus inadvertently converting
128+
@@ -487,7 +517,7 @@ vdev_bio_associate_blkg(struct bio *bio)
129+
ASSERT3P(q, !=, NULL);
130+
ASSERT3P(bio->bi_blkg, ==, NULL);
131+
132+
- if (q->root_blkg && blkg_tryget(q->root_blkg))
133+
+ if (q->root_blkg && vdev_blkg_tryget(q->root_blkg))
134+
bio->bi_blkg = q->root_blkg;
135+
}
136+
#define bio_associate_blkg vdev_bio_associate_blkg

0 commit comments

Comments
 (0)