Linux 5.5 compat: blkg_tryget()
Commit https://github.com/torvalds/linux/commit/9e8d42a0f accidentally converted the static inline function blkg_tryget() to GPL-only for kernels built with CONFIG_PREEMPT_RCU=y and CONFIG_BLK_CGROUP=y. Resolve the build issue by providing our own equivalent functionality when needed which uses rcu_read_lock_sched() internally as before. Reviewed-by: Tony Hutter <hutter2@llnl.gov> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #9745 Closes #10072
This commit is contained in:
parent
2ce90dca91
commit
bd0d24e09b
|
@ -331,6 +331,44 @@ AC_DEFUN([ZFS_AC_KERNEL_BIO_CURRENT_BIO_LIST], [
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
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], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO], [
|
||||||
ZFS_AC_KERNEL_SRC_REQ
|
ZFS_AC_KERNEL_SRC_REQ
|
||||||
ZFS_AC_KERNEL_SRC_BIO_OPS
|
ZFS_AC_KERNEL_SRC_BIO_OPS
|
||||||
|
@ -340,6 +378,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO], [
|
||||||
ZFS_AC_KERNEL_SRC_BIO_BVEC_ITER
|
ZFS_AC_KERNEL_SRC_BIO_BVEC_ITER
|
||||||
ZFS_AC_KERNEL_SRC_BIO_SUBMIT_BIO
|
ZFS_AC_KERNEL_SRC_BIO_SUBMIT_BIO
|
||||||
ZFS_AC_KERNEL_SRC_BIO_CURRENT_BIO_LIST
|
ZFS_AC_KERNEL_SRC_BIO_CURRENT_BIO_LIST
|
||||||
|
ZFS_AC_KERNEL_SRC_BLKG_TRYGET
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_BIO], [
|
AC_DEFUN([ZFS_AC_KERNEL_BIO], [
|
||||||
|
@ -360,4 +399,5 @@ AC_DEFUN([ZFS_AC_KERNEL_BIO], [
|
||||||
ZFS_AC_KERNEL_BIO_BVEC_ITER
|
ZFS_AC_KERNEL_BIO_BVEC_ITER
|
||||||
ZFS_AC_KERNEL_BIO_SUBMIT_BIO
|
ZFS_AC_KERNEL_BIO_SUBMIT_BIO
|
||||||
ZFS_AC_KERNEL_BIO_CURRENT_BIO_LIST
|
ZFS_AC_KERNEL_BIO_CURRENT_BIO_LIST
|
||||||
|
ZFS_AC_KERNEL_BLKG_TRYGET
|
||||||
])
|
])
|
||||||
|
|
|
@ -456,6 +456,36 @@ vdev_submit_bio_impl(struct bio *bio)
|
||||||
|
|
||||||
#ifdef HAVE_BIO_SET_DEV
|
#ifdef HAVE_BIO_SET_DEV
|
||||||
#if defined(CONFIG_BLK_CGROUP) && defined(HAVE_BIO_SET_DEV_GPL_ONLY)
|
#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
|
* The Linux 5.0 kernel updated the bio_set_dev() macro so it calls the
|
||||||
* GPL-only bio_associate_blkg() symbol thus inadvertently converting
|
* GPL-only bio_associate_blkg() symbol thus inadvertently converting
|
||||||
|
@ -470,7 +500,7 @@ vdev_bio_associate_blkg(struct bio *bio)
|
||||||
ASSERT3P(q, !=, NULL);
|
ASSERT3P(q, !=, NULL);
|
||||||
ASSERT3P(bio->bi_blkg, ==, 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;
|
bio->bi_blkg = q->root_blkg;
|
||||||
}
|
}
|
||||||
#define bio_associate_blkg vdev_bio_associate_blkg
|
#define bio_associate_blkg vdev_bio_associate_blkg
|
||||||
|
|
Loading…
Reference in New Issue