|
| 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