])
])
+dnl #
+dnl # Linux 5.5 API,
+dnl #
+dnl # The Linux 5.5 kernel updated percpu_ref_tryget() which is inlined by
+dnl # blkg_tryget() to use rcu_read_lock() instead of rcu_read_lock_sched().
+dnl # As a side effect the function was converted to GPL-only.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKG_TRYGET], [
+ ZFS_LINUX_TEST_SRC([blkg_tryget], [
+ #include <linux/blk-cgroup.h>
+ #include <linux/bio.h>
+ #include <linux/fs.h>
+ ],[
+ struct blkcg_gq blkg __attribute__ ((unused));
+ bool rc __attribute__ ((unused));
+ rc = blkg_tryget(&blkg);
+ ], [], [$ZFS_META_LICENSE])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_BLKG_TRYGET], [
+ AC_MSG_CHECKING([whether blkg_tryget() is available])
+ ZFS_LINUX_TEST_RESULT([blkg_tryget], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLKG_TRYGET, 1, [blkg_tryget() is available])
+
+ AC_MSG_CHECKING([whether blkg_tryget() is GPL-only])
+ ZFS_LINUX_TEST_RESULT([blkg_tryget_license], [
+ AC_MSG_RESULT(no)
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLKG_TRYGET_GPL_ONLY, 1,
+ [blkg_tryget() GPL-only])
+ ])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+])
+
AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO], [
ZFS_AC_KERNEL_SRC_REQ
ZFS_AC_KERNEL_SRC_BIO_OPS
ZFS_AC_KERNEL_SRC_BIO_BVEC_ITER
ZFS_AC_KERNEL_SRC_BIO_SUBMIT_BIO
ZFS_AC_KERNEL_SRC_BIO_CURRENT_BIO_LIST
+ ZFS_AC_KERNEL_SRC_BLKG_TRYGET
])
AC_DEFUN([ZFS_AC_KERNEL_BIO], [
ZFS_AC_KERNEL_BIO_BVEC_ITER
ZFS_AC_KERNEL_BIO_SUBMIT_BIO
ZFS_AC_KERNEL_BIO_CURRENT_BIO_LIST
+ ZFS_AC_KERNEL_BLKG_TRYGET
])
#ifdef HAVE_BIO_SET_DEV
#if defined(CONFIG_BLK_CGROUP) && defined(HAVE_BIO_SET_DEV_GPL_ONLY)
+/*
+ * The Linux 5.5 kernel updated percpu_ref_tryget() which is inlined by
+ * blkg_tryget() to use rcu_read_lock() instead of rcu_read_lock_sched().
+ * As a side effect the function was converted to GPL-only. Define our
+ * own version when needed which uses rcu_read_lock_sched().
+ */
+#if defined(HAVE_BLKG_TRYGET_GPL_ONLY)
+static inline bool
+vdev_blkg_tryget(struct blkcg_gq *blkg)
+{
+ struct percpu_ref *ref = &blkg->refcnt;
+ unsigned long __percpu *count;
+ bool rc;
+
+ rcu_read_lock_sched();
+
+ if (__ref_is_percpu(ref, &count)) {
+ this_cpu_inc(*count);
+ rc = true;
+ } else {
+ rc = atomic_long_inc_not_zero(&ref->count);
+ }
+
+ rcu_read_unlock_sched();
+
+ return (rc);
+}
+#elif defined(HAVE_BLKG_TRYGET)
+#define vdev_blkg_tryget(bg) blkg_tryget(bg)
+#endif
/*
* The Linux 5.0 kernel updated the bio_set_dev() macro so it calls the
* GPL-only bio_associate_blkg() symbol thus inadvertently converting
ASSERT3P(q, !=, NULL);
ASSERT3P(bio->bi_blkg, ==, NULL);
- if (q->root_blkg && blkg_tryget(q->root_blkg))
+ if (q->root_blkg && vdev_blkg_tryget(q->root_blkg))
bio->bi_blkg = q->root_blkg;
}
#define bio_associate_blkg vdev_bio_associate_blkg