Hello community, here is the log from the commit of package userspace-rcu for openSUSE:Factory checked in at 2015-10-01 09:29:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/userspace-rcu (Old) and /work/SRC/openSUSE:Factory/.userspace-rcu.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "userspace-rcu" Changes: -------- --- /work/SRC/openSUSE:Factory/userspace-rcu/userspace-rcu.changes 2014-12-03 22:49:23.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.userspace-rcu.new/userspace-rcu.changes 2015-10-01 09:29:31.000000000 +0200 @@ -1,0 +2,25 @@ +Tue Sep 29 19:09:49 UTC 2015 - [email protected] + +- remove dependency on gpg-offline, is done by source validator +- drop userspace-rcu-ppc64le.patch, included in + userspace-rcu-aarch64.patch + +------------------------------------------------------------------- +Mon Aug 31 19:14:52 UTC 2015 - [email protected] + +- add userspace-rcu-aarch64.patch (fate#318370) + enables build for aarch64 + +------------------------------------------------------------------- +Tue Jul 28 22:32:41 UTC 2015 - [email protected] + +- Update to version 0.8,7 (FATE#319273) + Changelog 0.8.7: + * Fix: deadlock when thread join is issued in read-side C.S. + * Fix: rename RCU_DEBUG to DEBUG_RCU in urcu-qsbr.h + * Mark braced-groups within expressions with __extension__ + * Fix: compat_futex_noasync race condition + * Fix: documentation: urcu-pointer.h: s/rcu_dereference_pointer/rcu_dereference/ + * Fix: call rcu should call internal RCU API + +------------------------------------------------------------------- Old: ---- userspace-rcu-0.8.6.tar.bz2 userspace-rcu-0.8.6.tar.bz2.asc userspace-rcu-ppc64le.patch New: ---- userspace-rcu-0.8.7.tar.bz2 userspace-rcu-0.8.7.tar.bz2.asc userspace-rcu-aarch64.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ userspace-rcu.spec ++++++ --- /var/tmp/diff_new_pack.ctFeqz/_old 2015-10-01 09:29:32.000000000 +0200 +++ /var/tmp/diff_new_pack.ctFeqz/_new 2015-10-01 09:29:32.000000000 +0200 @@ -2,7 +2,7 @@ # # spec file for package userspace-rcu # -# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # Copyright (c) 2012 Pascal Bleser <[email protected]> # # All modifications and additions to the file contributed by third parties @@ -19,7 +19,7 @@ Name: userspace-rcu -Version: 0.8.6 +Version: 0.8.7 Release: 0 %define soname 2 Summary: Userspace Read-Copy-Update Library @@ -28,14 +28,13 @@ Source0: http://lttng.org/files/urcu/userspace-rcu-%{version}.tar.bz2 Source1: http://lttng.org/files/urcu/userspace-rcu-%{version}.tar.bz2.asc Source2: userspace-rcu.keyring -Patch0: userspace-rcu-ppc64le.patch +Patch1: userspace-rcu-aarch64.patch Url: http://lttng.org/urcu BuildRoot: %{_tmppath}/%{name}-%{version}-build +BuildRequires: automake BuildRequires: gcc BuildRequires: glibc-devel -%if 0%{?suse_version} >= 1230 -BuildRequires: gpg-offline -%endif +BuildRequires: libtool BuildRequires: make BuildRequires: pkgconfig @@ -70,11 +69,11 @@ accesses to detect grace periods after which memory reclamation is possible. %prep -%{?gpg_verify: %gpg_verify %{SOURCE1}} %setup -q -%patch0 -p1 +%patch1 -p1 %build +autoreconf -fi %configure --disable-silent-rules --disable-static %__make %{?_smp_mflags} ++++++ userspace-rcu-0.8.6.tar.bz2 -> userspace-rcu-0.8.7.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/ChangeLog new/userspace-rcu-0.8.7/ChangeLog --- old/userspace-rcu-0.8.6/ChangeLog 2014-11-04 17:04:15.000000000 +0100 +++ new/userspace-rcu-0.8.7/ChangeLog 2015-04-28 20:51:21.000000000 +0200 @@ -1,3 +1,11 @@ +2015-04-28 Userspace RCU 0.8.7 + * Fix: deadlock when thread join is issued in read-side C.S. + * Fix: rename RCU_DEBUG to DEBUG_RCU in urcu-qsbr.h + * Mark braced-groups within expressions with __extension__ + * Fix: compat_futex_noasync race condition + * Fix: documentation: urcu-pointer.h: s/rcu_dereference_pointer/rcu_dereference/ + * Fix: call rcu should call internal RCU API + 2014-11-04 Userspace RCU 0.8.6 * Fix: silence gcc -Wextra warning * compiler: use __GNUC__ instead of the undefined __GNUC_MAJOR__ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/aclocal.m4 new/userspace-rcu-0.8.7/aclocal.m4 --- old/userspace-rcu-0.8.6/aclocal.m4 2014-11-04 17:04:33.000000000 +0100 +++ new/userspace-rcu-0.8.7/aclocal.m4 2015-04-28 20:52:22.000000000 +0200 @@ -103,10 +103,9 @@ # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], -[dnl Rely on autoconf to set up CDPATH properly. -AC_PREREQ([2.50])dnl -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/compat_futex.c new/userspace-rcu-0.8.7/compat_futex.c --- old/userspace-rcu-0.8.6/compat_futex.c 2014-10-27 17:42:46.000000000 +0100 +++ new/userspace-rcu-0.8.7/compat_futex.c 2015-03-17 23:01:04.000000000 +0100 @@ -72,17 +72,26 @@ assert(!ret); switch (op) { case FUTEX_WAIT: - if (*uaddr != val) - goto end; - pthread_cond_wait(&__urcu_compat_futex_cond, &__urcu_compat_futex_lock); + /* + * Wait until *uaddr is changed to something else than "val". + * Comparing *uaddr content against val figures out which + * thread has been awakened. + */ + while (*uaddr == val) + pthread_cond_wait(&__urcu_compat_futex_cond, + &__urcu_compat_futex_lock); break; case FUTEX_WAKE: + /* + * Each wake is sending a broadcast, thus attempting wakeup of + * all awaiting threads, independently of their respective + * uaddr. + */ pthread_cond_broadcast(&__urcu_compat_futex_cond); break; default: gret = -EINVAL; } -end: ret = pthread_mutex_unlock(&__urcu_compat_futex_lock); assert(!ret); return gret; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/configure new/userspace-rcu-0.8.7/configure --- old/userspace-rcu-0.8.6/configure 2014-11-04 17:04:35.000000000 +0100 +++ new/userspace-rcu-0.8.7/configure 2015-04-28 20:52:24.000000000 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for userspace-rcu 0.8.6. +# Generated by GNU Autoconf 2.69 for userspace-rcu 0.8.7. # # Report bugs to <mathieu dot desnoyers at efficios dot com>. # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='userspace-rcu' PACKAGE_TARNAME='userspace-rcu' -PACKAGE_VERSION='0.8.6' -PACKAGE_STRING='userspace-rcu 0.8.6' +PACKAGE_VERSION='0.8.7' +PACKAGE_STRING='userspace-rcu 0.8.7' PACKAGE_BUGREPORT='mathieu dot desnoyers at efficios dot com' PACKAGE_URL='' @@ -1326,7 +1326,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures userspace-rcu 0.8.6 to adapt to many kinds of systems. +\`configure' configures userspace-rcu 0.8.7 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1397,7 +1397,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of userspace-rcu 0.8.6:";; + short | recursive ) echo "Configuration of userspace-rcu 0.8.7:";; esac cat <<\_ACEOF @@ -1506,7 +1506,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -userspace-rcu configure 0.8.6 +userspace-rcu configure 0.8.7 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1929,7 +1929,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by userspace-rcu $as_me 0.8.6, which was +It was created by userspace-rcu $as_me 0.8.7, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2599,8 +2599,8 @@ ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in @@ -2913,7 +2913,7 @@ # Define the identity of the package. PACKAGE='userspace-rcu' - VERSION='0.8.6' + VERSION='0.8.7' cat >>confdefs.h <<_ACEOF @@ -13817,7 +13817,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by userspace-rcu $as_me 0.8.6, which was +This file was extended by userspace-rcu $as_me 0.8.7, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -13887,7 +13887,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -userspace-rcu config.status 0.8.6 +userspace-rcu config.status 0.8.7 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/configure.ac new/userspace-rcu-0.8.7/configure.ac --- old/userspace-rcu-0.8.6/configure.ac 2014-11-04 17:04:28.000000000 +0100 +++ new/userspace-rcu-0.8.7/configure.ac 2015-04-28 20:50:46.000000000 +0200 @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. -AC_INIT([userspace-rcu],[0.8.6],[mathieu dot desnoyers at efficios dot com]) +AC_INIT([userspace-rcu],[0.8.7],[mathieu dot desnoyers at efficios dot com]) # Following the numbering scheme proposed by libtool for the library version # http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/urcu/arch/ppc.h new/userspace-rcu-0.8.7/urcu/arch/ppc.h --- old/userspace-rcu-0.8.6/urcu/arch/ppc.h 2014-03-01 16:30:42.000000000 +0100 +++ new/userspace-rcu-0.8.7/urcu/arch/ppc.h 2015-04-28 20:35:59.000000000 +0200 @@ -58,6 +58,7 @@ #define cmm_smp_wmb() __asm__ __volatile__ (LWSYNC_OPCODE:::"memory") #define mftbl() \ + __extension__ \ ({ \ unsigned long rval; \ __asm__ __volatile__ ("mftbl %0" : "=r" (rval)); \ @@ -65,6 +66,7 @@ }) #define mftbu() \ + __extension__ \ ({ \ unsigned long rval; \ __asm__ __volatile__ ("mftbu %0" : "=r" (rval)); \ @@ -72,6 +74,7 @@ }) #define mftb() \ + __extension__ \ ({ \ unsigned long long rval; \ __asm__ __volatile__ ("mftb %0" : "=r" (rval)); \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/urcu/compiler.h new/userspace-rcu-0.8.7/urcu/compiler.h --- old/userspace-rcu-0.8.6/urcu/compiler.h 2014-11-04 17:02:11.000000000 +0100 +++ new/userspace-rcu-0.8.7/urcu/compiler.h 2015-04-28 20:50:46.000000000 +0200 @@ -64,6 +64,7 @@ * @member: name of the field within the object. */ #define caa_container_of(ptr, type, member) \ + __extension__ \ ({ \ const __typeof__(((type *) NULL)->member) * __ptr = (ptr); \ (type *)((char *)__ptr - offsetof(type, member)); \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/urcu/map/urcu-mp.h new/userspace-rcu-0.8.7/urcu/map/urcu-mp.h --- old/userspace-rcu-0.8.6/urcu/map/urcu-mp.h 1970-01-01 01:00:00.000000000 +0100 +++ new/userspace-rcu-0.8.7/urcu/map/urcu-mp.h 2015-04-07 14:09:38.000000000 +0200 @@ -0,0 +1,85 @@ +#ifndef _URCU_MAP_H +#define _URCU_MAP_H + +/* + * urcu/map/urcu-mp.h + * + * Userspace RCU header -- name mapping to allow multiple flavors to be + * used in the same executable. + * + * Copyright (c) 2009 Mathieu Desnoyers <[email protected]> + * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. + * + * LGPL-compatible code should include this header with : + * + * #define _LGPL_SOURCE + * #include <urcu.h> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * IBM's contributions to this file may be relicensed under LGPLv2 or later. + */ + +/* Mapping macros to allow multiple flavors in a single binary. */ + +#define rcu_read_lock rcu_read_lock_mp +#define _rcu_read_lock _rcu_read_lock_mp +#define rcu_read_unlock rcu_read_unlock_mp +#define _rcu_read_unlock _rcu_read_unlock_mp +#define rcu_read_ongoing rcu_read_ongoing_mp +#define _rcu_read_ongoing _rcu_read_ongoing_mp +#define rcu_register_thread rcu_register_thread_mp +#define rcu_unregister_thread rcu_unregister_thread_mp +#define rcu_init rcu_init_mp +#define synchronize_rcu synchronize_rcu_mp +#define rcu_reader rcu_reader_mp +#define rcu_gp rcu_gp_mp + +#define rcu_quiescent_state rcu_quiescent_state_mp +#define rcu_thread_offline rcu_thread_offline_mp +#define rcu_thread_online rcu_thread_online_mp +#define rcu_read_lock_online rcu_read_lock_online_mp +#define rcu_read_unlock_online rcu_read_unlock_online_mp + +#define get_cpu_call_rcu_data get_cpu_call_rcu_data_mp +#define get_call_rcu_thread get_call_rcu_thread_mp +#define create_call_rcu_data create_call_rcu_data_mp +#define set_cpu_call_rcu_data set_cpu_call_rcu_data_mp +#define get_default_call_rcu_data get_default_call_rcu_data_mp +#define get_call_rcu_data get_call_rcu_data_mp +#define get_thread_call_rcu_data get_thread_call_rcu_data_mp +#define set_thread_call_rcu_data set_thread_call_rcu_data_mp +#define create_all_cpu_call_rcu_data create_all_cpu_call_rcu_data_mp +#define free_all_cpu_call_rcu_data free_all_cpu_call_rcu_data_mp +#define call_rcu call_rcu_mp +#define call_rcu_data_free call_rcu_data_free_mp +#define call_rcu_before_fork call_rcu_before_fork_mp +#define call_rcu_after_fork_parent call_rcu_after_fork_parent_mp +#define call_rcu_after_fork_child call_rcu_after_fork_child_mp +#define rcu_barrier rcu_barrier_mp + +#define defer_rcu defer_rcu_mp +#define rcu_defer_register_thread rcu_defer_register_thread_mp +#define rcu_defer_unregister_thread rcu_defer_unregister_thread_mp +#define rcu_defer_barrier rcu_defer_barrier_mp +#define rcu_defer_barrier_thread rcu_defer_barrier_thread_mp +#define rcu_defer_exit rcu_defer_exit_mp + +#define rcu_flavor rcu_flavor_mp + +/* Specific to mpARRIER flavor */ +#define rcu_has_sys_mparrier rcu_has_sys_mparrier_mp + +#endif /* _URCU_MAP_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/urcu/static/urcu-pointer.h new/userspace-rcu-0.8.7/urcu/static/urcu-pointer.h --- old/userspace-rcu-0.8.6/urcu/static/urcu-pointer.h 2014-03-01 16:30:42.000000000 +0100 +++ new/userspace-rcu-0.8.7/urcu/static/urcu-pointer.h 2015-04-28 20:35:59.000000000 +0200 @@ -64,7 +64,9 @@ * meets the 10-line criterion in LGPL, allowing this function to be * expanded directly in non-LGPL code. */ -#define _rcu_dereference(p) ({ \ +#define _rcu_dereference(p) \ + __extension__ \ + ({ \ __typeof__(p) _________p1 = CMM_LOAD_SHARED(p); \ cmm_smp_read_barrier_depends(); \ (_________p1); \ @@ -82,6 +84,7 @@ * expanded directly in non-LGPL code. */ #define _rcu_cmpxchg_pointer(p, old, _new) \ + __extension__ \ ({ \ __typeof__(*p) _________pold = (old); \ __typeof__(*p) _________pnew = (_new); \ @@ -101,6 +104,7 @@ * expanded directly in non-LGPL code. */ #define _rcu_xchg_pointer(p, v) \ + __extension__ \ ({ \ __typeof__(*p) _________pv = (v); \ if (!__builtin_constant_p(v) || \ @@ -129,7 +133,7 @@ * them. It also makes sure the compiler does not reorder code initializing the * data structure before its publication. * - * Should match rcu_dereference_pointer(). + * Should match rcu_dereference(). * * This macro is less than 10 lines long. The intent is that this macro * meets the 10-line criterion in LGPL, allowing this function to be diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/urcu/system.h new/userspace-rcu-0.8.7/urcu/system.h --- old/userspace-rcu-0.8.6/urcu/system.h 2014-03-01 16:30:42.000000000 +0100 +++ new/userspace-rcu-0.8.7/urcu/system.h 2015-04-28 20:35:59.000000000 +0200 @@ -32,6 +32,7 @@ * Load a data from shared memory, doing a cache flush if required. */ #define CMM_LOAD_SHARED(p) \ + __extension__ \ ({ \ cmm_smp_rmc(); \ _CMM_LOAD_SHARED(p); \ @@ -41,13 +42,14 @@ * Identify a shared store. A cmm_smp_wmc() or cmm_smp_mc() should * follow the store. */ -#define _CMM_STORE_SHARED(x, v) ({ CMM_ACCESS_ONCE(x) = (v); }) +#define _CMM_STORE_SHARED(x, v) __extension__ ({ CMM_ACCESS_ONCE(x) = (v); }) /* * Store v into x, where x is located in shared memory. Performs the * required cache flush after writing. Returns v. */ #define CMM_STORE_SHARED(x, v) \ + __extension__ \ ({ \ __typeof__(x) _v = _CMM_STORE_SHARED(x, v); \ cmm_smp_wmc(); \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/urcu-bp.c new/userspace-rcu-0.8.7/urcu-bp.c --- old/userspace-rcu-0.8.6/urcu-bp.c 2014-11-04 17:02:31.000000000 +0100 +++ new/userspace-rcu-0.8.7/urcu-bp.c 2015-04-28 20:50:46.000000000 +0200 @@ -99,7 +99,21 @@ static void __attribute__((destructor)) _rcu_bp_exit(void); +/* + * rcu_gp_lock ensures mutual exclusion between threads calling + * synchronize_rcu(). + */ static pthread_mutex_t rcu_gp_lock = PTHREAD_MUTEX_INITIALIZER; +/* + * rcu_registry_lock ensures mutual exclusion between threads + * registering and unregistering themselves to/from the registry, and + * with threads reading that registry from synchronize_rcu(). However, + * this lock is not held all the way through the completion of awaiting + * for the grace period. It is sporadically released between iterations + * on the registry. + * rcu_registry_lock may nest inside rcu_gp_lock. + */ +static pthread_mutex_t rcu_registry_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER; static int initialized; @@ -165,6 +179,10 @@ urcu_die(ret); } +/* + * Always called with rcu_registry lock held. Releases this lock between + * iterations and grabs it again. Holds the lock when it returns. + */ static void wait_for_readers(struct cds_list_head *input_readers, struct cds_list_head *cur_snap_readers, struct cds_list_head *qsreaders) @@ -207,10 +225,14 @@ if (cds_list_empty(input_readers)) { break; } else { + /* Temporarily unlock the registry lock. */ + mutex_unlock(&rcu_registry_lock); if (wait_loops >= RCU_QS_ACTIVE_ATTEMPTS) (void) poll(NULL, 0, RCU_SLEEP_DELAY_MS); else caa_cpu_relax(); + /* Re-lock the registry lock before the next loop. */ + mutex_lock(&rcu_registry_lock); } } } @@ -229,6 +251,8 @@ mutex_lock(&rcu_gp_lock); + mutex_lock(&rcu_registry_lock); + if (cds_list_empty(®istry)) goto out; @@ -239,6 +263,8 @@ /* * Wait for readers to observe original parity or be quiescent. + * wait_for_readers() can release and grab again rcu_registry_lock + * interally. */ wait_for_readers(®istry, &cur_snap_readers, &qsreaders); @@ -268,6 +294,8 @@ /* * Wait for readers to observe new parity or be quiescent. + * wait_for_readers() can release and grab again rcu_registry_lock + * interally. */ wait_for_readers(&cur_snap_readers, NULL, &qsreaders); @@ -282,6 +310,7 @@ */ cmm_smp_mb(); out: + mutex_unlock(&rcu_registry_lock); mutex_unlock(&rcu_gp_lock); ret = pthread_sigmask(SIG_SETMASK, &oldmask, NULL); assert(!ret); @@ -490,9 +519,9 @@ */ rcu_bp_init(); - mutex_lock(&rcu_gp_lock); + mutex_lock(&rcu_registry_lock); add_thread(); - mutex_unlock(&rcu_gp_lock); + mutex_unlock(&rcu_registry_lock); end: ret = pthread_sigmask(SIG_SETMASK, &oldmask, NULL); if (ret) @@ -513,9 +542,9 @@ if (ret) abort(); - mutex_lock(&rcu_gp_lock); + mutex_lock(&rcu_registry_lock); remove_thread(rcu_reader_reg); - mutex_unlock(&rcu_gp_lock); + mutex_unlock(&rcu_registry_lock); ret = pthread_sigmask(SIG_SETMASK, &oldmask, NULL); if (ret) abort(); @@ -578,9 +607,10 @@ } /* - * Holding the rcu_gp_lock across fork will make sure we fork() don't race with - * a concurrent thread executing with this same lock held. This ensures that the - * registry is in a coherent state in the child. + * Holding the rcu_gp_lock and rcu_registry_lock across fork will make + * sure we fork() don't race with a concurrent thread executing with + * any of those locks held. This ensures that the registry and data + * protected by rcu_gp_lock are in a coherent state in the child. */ void rcu_bp_before_fork(void) { @@ -592,6 +622,7 @@ ret = pthread_sigmask(SIG_BLOCK, &newmask, &oldmask); assert(!ret); mutex_lock(&rcu_gp_lock); + mutex_lock(&rcu_registry_lock); saved_fork_signal_mask = oldmask; } @@ -601,6 +632,7 @@ int ret; oldmask = saved_fork_signal_mask; + mutex_unlock(&rcu_registry_lock); mutex_unlock(&rcu_gp_lock); ret = pthread_sigmask(SIG_SETMASK, &oldmask, NULL); assert(!ret); @@ -608,7 +640,7 @@ /* * Prune all entries from registry except our own thread. Fits the Linux - * fork behavior. Called with rcu_gp_lock held. + * fork behavior. Called with rcu_gp_lock and rcu_registry_lock held. */ static void urcu_bp_prune_registry(void) @@ -636,6 +668,7 @@ urcu_bp_prune_registry(); oldmask = saved_fork_signal_mask; + mutex_unlock(&rcu_registry_lock); mutex_unlock(&rcu_gp_lock); ret = pthread_sigmask(SIG_SETMASK, &oldmask, NULL); assert(!ret); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/urcu-bp.h new/userspace-rcu-0.8.7/urcu-bp.h --- old/userspace-rcu-0.8.6/urcu-bp.h 2014-10-24 23:16:28.000000000 +0200 +++ new/userspace-rcu-0.8.7/urcu-bp.h 2015-04-28 20:50:46.000000000 +0200 @@ -94,6 +94,7 @@ extern void *rcu_dereference_sym_bp(void *p); #define rcu_dereference_bp(p) \ + __extension__ \ ({ \ __typeof__(p) _________p1 = URCU_FORCE_CAST(__typeof__(p), \ rcu_dereference_sym_bp(URCU_FORCE_CAST(void *, p))); \ @@ -102,6 +103,7 @@ extern void *rcu_cmpxchg_pointer_sym_bp(void **p, void *old, void *_new); #define rcu_cmpxchg_pointer_bp(p, old, _new) \ + __extension__ \ ({ \ __typeof__(*(p)) _________pold = (old); \ __typeof__(*(p)) _________pnew = (_new); \ @@ -114,6 +116,7 @@ extern void *rcu_xchg_pointer_sym_bp(void **p, void *v); #define rcu_xchg_pointer_bp(p, v) \ + __extension__ \ ({ \ __typeof__(*(p)) _________pv = (v); \ __typeof__(*(p)) _________p1 = URCU_FORCE_CAST(__typeof__(*(p)),\ @@ -124,6 +127,7 @@ extern void *rcu_set_pointer_sym_bp(void **p, void *v); #define rcu_set_pointer_bp(p, v) \ + __extension__ \ ({ \ __typeof__(*(p)) _________pv = (v); \ __typeof__(*(p)) _________p1 = URCU_FORCE_CAST(__typeof__(*(p)), \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/urcu-call-rcu-impl.h new/userspace-rcu-0.8.7/urcu-call-rcu-impl.h --- old/userspace-rcu-0.8.6/urcu-call-rcu-impl.h 2014-10-27 17:42:46.000000000 +0100 +++ new/userspace-rcu-0.8.7/urcu-call-rcu-impl.h 2015-04-28 20:50:46.000000000 +0200 @@ -669,10 +669,10 @@ struct call_rcu_data *crdp; /* Holding rcu read-side lock across use of per-cpu crdp */ - rcu_read_lock(); + _rcu_read_lock(); crdp = get_call_rcu_data(); _call_rcu(head, func, crdp); - rcu_read_unlock(); + _rcu_read_unlock(); } /* @@ -804,14 +804,14 @@ int was_online; /* Put in offline state in QSBR. */ - was_online = rcu_read_ongoing(); + was_online = _rcu_read_ongoing(); if (was_online) rcu_thread_offline(); /* * Calling a rcu_barrier() within a RCU read-side critical * section is an error. */ - if (rcu_read_ongoing()) { + if (_rcu_read_ongoing()) { static int warned = 0; if (!warned) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/urcu-pointer.h new/userspace-rcu-0.8.7/urcu-pointer.h --- old/userspace-rcu-0.8.6/urcu-pointer.h 2014-10-24 23:16:28.000000000 +0200 +++ new/userspace-rcu-0.8.7/urcu-pointer.h 2015-04-28 20:50:46.000000000 +0200 @@ -66,6 +66,7 @@ extern void *rcu_dereference_sym(void *p); #define rcu_dereference(p) \ + __extension__ \ ({ \ __typeof__(p) _________p1 = URCU_FORCE_CAST(__typeof__(p), \ rcu_dereference_sym(URCU_FORCE_CAST(void *, p))); \ @@ -74,6 +75,7 @@ extern void *rcu_cmpxchg_pointer_sym(void **p, void *old, void *_new); #define rcu_cmpxchg_pointer(p, old, _new) \ + __extension__ \ ({ \ __typeof__(*(p)) _________pold = (old); \ __typeof__(*(p)) _________pnew = (_new); \ @@ -86,6 +88,7 @@ extern void *rcu_xchg_pointer_sym(void **p, void *v); #define rcu_xchg_pointer(p, v) \ + __extension__ \ ({ \ __typeof__(*(p)) _________pv = (v); \ __typeof__(*(p)) _________p1 = URCU_FORCE_CAST(__typeof__(*(p)), \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/urcu-qsbr.c new/userspace-rcu-0.8.7/urcu-qsbr.c --- old/userspace-rcu-0.8.6/urcu-qsbr.c 2014-11-04 17:02:31.000000000 +0100 +++ new/userspace-rcu-0.8.7/urcu-qsbr.c 2015-04-28 20:50:46.000000000 +0200 @@ -52,7 +52,21 @@ void __attribute__((destructor)) rcu_exit(void); +/* + * rcu_gp_lock ensures mutual exclusion between threads calling + * synchronize_rcu(). + */ static pthread_mutex_t rcu_gp_lock = PTHREAD_MUTEX_INITIALIZER; +/* + * rcu_registry_lock ensures mutual exclusion between threads + * registering and unregistering themselves to/from the registry, and + * with threads reading that registry from synchronize_rcu(). However, + * this lock is not held all the way through the completion of awaiting + * for the grace period. It is sporadically released between iterations + * on the registry. + * rcu_registry_lock may nest inside rcu_gp_lock. + */ +static pthread_mutex_t rcu_registry_lock = PTHREAD_MUTEX_INITIALIZER; struct rcu_gp rcu_gp = { .ctr = RCU_GP_ONLINE }; /* @@ -117,6 +131,10 @@ NULL, NULL, 0); } +/* + * Always called with rcu_registry lock held. Releases this lock between + * iterations and grabs it again. Holds the lock when it returns. + */ static void wait_for_readers(struct cds_list_head *input_readers, struct cds_list_head *cur_snap_readers, struct cds_list_head *qsreaders) @@ -176,6 +194,8 @@ } break; } else { + /* Temporarily unlock the registry lock. */ + mutex_unlock(&rcu_registry_lock); if (wait_loops >= RCU_QS_ACTIVE_ATTEMPTS) { wait_gp(); } else { @@ -185,6 +205,8 @@ cmm_smp_mb(); #endif /* #else #ifndef HAS_INCOHERENT_CACHES */ } + /* Re-lock the registry lock before the next loop. */ + mutex_lock(&rcu_registry_lock); } } } @@ -238,11 +260,15 @@ */ urcu_move_waiters(&waiters, &gp_waiters); + mutex_lock(&rcu_registry_lock); + if (cds_list_empty(®istry)) goto out; /* * Wait for readers to observe original parity or be quiescent. + * wait_for_readers() can release and grab again rcu_registry_lock + * interally. */ wait_for_readers(®istry, &cur_snap_readers, &qsreaders); @@ -284,6 +310,8 @@ /* * Wait for readers to observe new parity or be quiescent. + * wait_for_readers() can release and grab again rcu_registry_lock + * interally. */ wait_for_readers(&cur_snap_readers, NULL, &qsreaders); @@ -292,6 +320,7 @@ */ cds_list_splice(&qsreaders, ®istry); out: + mutex_unlock(&rcu_registry_lock); mutex_unlock(&rcu_gp_lock); urcu_wake_all_waiters(&waiters); gp_end: @@ -344,6 +373,8 @@ */ urcu_move_waiters(&waiters, &gp_waiters); + mutex_lock(&rcu_registry_lock); + if (cds_list_empty(®istry)) goto out; @@ -368,6 +399,8 @@ /* * Wait for readers to observe new count of be quiescent. + * wait_for_readers() can release and grab again rcu_registry_lock + * interally. */ wait_for_readers(®istry, NULL, &qsreaders); @@ -376,6 +409,7 @@ */ cds_list_splice(&qsreaders, ®istry); out: + mutex_unlock(&rcu_registry_lock); mutex_unlock(&rcu_gp_lock); urcu_wake_all_waiters(&waiters); gp_end: @@ -425,9 +459,9 @@ URCU_TLS(rcu_reader).tid = pthread_self(); assert(URCU_TLS(rcu_reader).ctr == 0); - mutex_lock(&rcu_gp_lock); + mutex_lock(&rcu_registry_lock); cds_list_add(&URCU_TLS(rcu_reader).node, ®istry); - mutex_unlock(&rcu_gp_lock); + mutex_unlock(&rcu_registry_lock); _rcu_thread_online(); } @@ -438,9 +472,9 @@ * with a waiting writer. */ _rcu_thread_offline(); - mutex_lock(&rcu_gp_lock); + mutex_lock(&rcu_registry_lock); cds_list_del(&URCU_TLS(rcu_reader).node); - mutex_unlock(&rcu_gp_lock); + mutex_unlock(&rcu_registry_lock); } void rcu_exit(void) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/urcu-qsbr.h new/userspace-rcu-0.8.7/urcu-qsbr.h --- old/userspace-rcu-0.8.6/urcu-qsbr.h 2014-10-27 17:42:46.000000000 +0100 +++ new/userspace-rcu-0.8.7/urcu-qsbr.h 2015-04-28 20:50:46.000000000 +0200 @@ -43,6 +43,10 @@ #include <urcu/map/urcu-qsbr.h> +#ifdef RCU_DEBUG /* For backward compatibility */ +#define DEBUG_RCU +#endif + /* * Important ! * @@ -86,12 +90,12 @@ * QSBR read lock/unlock are guaranteed to be no-ops. Therefore, we expose them * in the LGPL header for any code to use. However, the debug version is not * nops and may contain sanity checks. To activate it, applications must be - * recompiled with -DRCU_DEBUG (even non-LGPL/GPL applications). This is the + * recompiled with -DDEBUG_RCU (even non-LGPL/GPL applications). This is the * best trade-off between license/performance/code triviality and * library debugging & tracing features we could come up with. */ -#if (!defined(BUILD_QSBR_LIB) && !defined(RCU_DEBUG)) +#if (!defined(BUILD_QSBR_LIB) && !defined(DEBUG_RCU)) static inline void rcu_read_lock(void) { @@ -101,12 +105,12 @@ { } -#else /* !RCU_DEBUG */ +#else /* !DEBUG_RCU */ extern void rcu_read_lock(void); extern void rcu_read_unlock(void); -#endif /* !RCU_DEBUG */ +#endif /* !DEBUG_RCU */ extern int rcu_read_ongoing(void); extern void rcu_quiescent_state(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/userspace-rcu-0.8.6/urcu.c new/userspace-rcu-0.8.7/urcu.c --- old/userspace-rcu-0.8.6/urcu.c 2014-11-04 17:02:31.000000000 +0100 +++ new/userspace-rcu-0.8.7/urcu.c 2015-04-28 20:50:46.000000000 +0200 @@ -100,7 +100,21 @@ void __attribute__((destructor)) rcu_exit(void); #endif +/* + * rcu_gp_lock ensures mutual exclusion between threads calling + * synchronize_rcu(). + */ static pthread_mutex_t rcu_gp_lock = PTHREAD_MUTEX_INITIALIZER; +/* + * rcu_registry_lock ensures mutual exclusion between threads + * registering and unregistering themselves to/from the registry, and + * with threads reading that registry from synchronize_rcu(). However, + * this lock is not held all the way through the completion of awaiting + * for the grace period. It is sporadically released between iterations + * on the registry. + * rcu_registry_lock may nest inside rcu_gp_lock. + */ +static pthread_mutex_t rcu_registry_lock = PTHREAD_MUTEX_INITIALIZER; struct rcu_gp rcu_gp = { .ctr = RCU_GP_COUNT }; /* @@ -226,6 +240,10 @@ NULL, NULL, 0); } +/* + * Always called with rcu_registry lock held. Releases this lock between + * iterations and grabs it again. Holds the lock when it returns. + */ static void wait_for_readers(struct cds_list_head *input_readers, struct cds_list_head *cur_snap_readers, struct cds_list_head *qsreaders) @@ -282,10 +300,14 @@ } break; } else { + /* Temporarily unlock the registry lock. */ + mutex_unlock(&rcu_registry_lock); if (wait_loops >= RCU_QS_ACTIVE_ATTEMPTS) wait_gp(); else caa_cpu_relax(); + /* Re-lock the registry lock before the next loop. */ + mutex_lock(&rcu_registry_lock); } #else /* #ifndef HAS_INCOHERENT_CACHES */ /* @@ -305,12 +327,16 @@ smp_mb_master(RCU_MB_GROUP); wait_gp_loops = 0; } + /* Temporarily unlock the registry lock. */ + mutex_unlock(&rcu_registry_lock); if (wait_loops >= RCU_QS_ACTIVE_ATTEMPTS) { wait_gp(); wait_gp_loops++; } else { caa_cpu_relax(); } + /* Re-lock the registry lock before the next loop. */ + mutex_lock(&rcu_registry_lock); } #endif /* #else #ifndef HAS_INCOHERENT_CACHES */ } @@ -348,17 +374,23 @@ */ urcu_move_waiters(&waiters, &gp_waiters); + mutex_lock(&rcu_registry_lock); + if (cds_list_empty(®istry)) goto out; - /* All threads should read qparity before accessing data structure - * where new ptr points to. Must be done within rcu_gp_lock because it - * iterates on reader threads.*/ + /* + * All threads should read qparity before accessing data structure + * where new ptr points to. Must be done within rcu_registry_lock + * because it iterates on reader threads. + */ /* Write new ptr before changing the qparity */ smp_mb_master(RCU_MB_GROUP); /* * Wait for readers to observe original parity or be quiescent. + * wait_for_readers() can release and grab again rcu_registry_lock + * interally. */ wait_for_readers(®istry, &cur_snap_readers, &qsreaders); @@ -399,6 +431,8 @@ /* * Wait for readers to observe new parity or be quiescent. + * wait_for_readers() can release and grab again rcu_registry_lock + * interally. */ wait_for_readers(&cur_snap_readers, NULL, &qsreaders); @@ -407,11 +441,14 @@ */ cds_list_splice(&qsreaders, ®istry); - /* Finish waiting for reader threads before letting the old ptr being - * freed. Must be done within rcu_gp_lock because it iterates on reader - * threads. */ + /* + * Finish waiting for reader threads before letting the old ptr + * being freed. Must be done within rcu_registry_lock because it + * iterates on reader threads. + */ smp_mb_master(RCU_MB_GROUP); out: + mutex_unlock(&rcu_registry_lock); mutex_unlock(&rcu_gp_lock); /* @@ -447,17 +484,17 @@ assert(URCU_TLS(rcu_reader).need_mb == 0); assert(!(URCU_TLS(rcu_reader).ctr & RCU_GP_CTR_NEST_MASK)); - mutex_lock(&rcu_gp_lock); + mutex_lock(&rcu_registry_lock); rcu_init(); /* In case gcc does not support constructor attribute */ cds_list_add(&URCU_TLS(rcu_reader).node, ®istry); - mutex_unlock(&rcu_gp_lock); + mutex_unlock(&rcu_registry_lock); } void rcu_unregister_thread(void) { - mutex_lock(&rcu_gp_lock); + mutex_lock(&rcu_registry_lock); cds_list_del(&URCU_TLS(rcu_reader).node); - mutex_unlock(&rcu_gp_lock); + mutex_unlock(&rcu_registry_lock); } #ifdef RCU_MEMBARRIER @@ -488,9 +525,9 @@ * rcu_init constructor. Called when the library is linked, but also when * reader threads are calling rcu_register_thread(). * Should only be called by a single thread at a given time. This is ensured by - * holing the rcu_gp_lock from rcu_register_thread() or by running at library - * load time, which should not be executed by multiple threads nor concurrently - * with rcu_register_thread() anyway. + * holing the rcu_registry_lock from rcu_register_thread() or by running + * at library load time, which should not be executed by multiple + * threads nor concurrently with rcu_register_thread() anyway. */ void rcu_init(void) { ++++++ userspace-rcu-aarch64.patch ++++++ From: Dimitri John Ledkov <[email protected]> Date: Wed, 12 Mar 2014 12:17:51 +0000 (-0400) Subject: Use gcc atomics on aarch64/powerpc64le X-Git-Url: http://git.lttng.org/?p=userspace-rcu.git;a=commitdiff_plain;h=3913336f0e763b4ab614aa6b6e41e20b481e50c3 Use gcc atomics on aarch64/powerpc64le Currently there are two fairly recent architectures, which at the moment can only be compiled with "gcc atomics" code path. The two new architectures are (GNU Types): * aarch64-linux-gnu (aka ARMv8, ARM64, AARCH64, etc) * powerpc64le-linux-gnu Signed-off-by: Mathieu Desnoyers <[email protected]> --- diff --git a/configure.ac b/configure.ac index 079c145..3368b33 100644 --- a/configure.ac +++ b/configure.ac @@ -69,6 +69,7 @@ AS_CASE([$host_cpu], [powerpc], [ARCHTYPE="ppc"], [ppc64], [ARCHTYPE="ppc"], [powerpc64], [ARCHTYPE="ppc"], + [powerpc64le], [ARCHTYPE="gcc"], [ppc], [ARCHTYPE="ppc"], [s390], [ARCHTYPE="s390"], [s390x], [ARCHTYPE="s390"], @@ -77,6 +78,7 @@ AS_CASE([$host_cpu], [alpha*], [ARCHTYPE="alpha"], [ia64], [ARCHTYPE="gcc"], [arm*], [ARCHTYPE="arm"], + [aarch64], [ARCHTYPE="gcc"], [mips*], [ARCHTYPE="mips"], [tile*], [ARCHTYPE="gcc"], [ARCHTYPE="unknown"]
