Skip to content

Commit

Permalink
Merge branches 'rcu/staging-core', 'rcu/staging-docs' and 'rcu/stagin…
Browse files Browse the repository at this point in the history
…g-kfree', remote-tracking branches 'paul/srcu-cf.2023.04.04a', 'fbq/rcu/lockdep.2023.03.27a' and 'fbq/rcu/rcutorture.2023.03.20a' into rcu/staging
  • Loading branch information
joelagnel committed Apr 5, 2023
6 parents 3c1566b + 09853fb + 1eacac3 + cefc0a5 + 5c5552d + 6bc6e6b commit 8ae9985
Show file tree
Hide file tree
Showing 43 changed files with 838 additions and 304 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ the following access functions:

Again, only one request in a given batch need actually carry out a
grace-period operation, which means there must be an efficient way to
identify which of many concurrent reqeusts will initiate the grace
identify which of many concurrent requests will initiate the grace
period, and that there be an efficient way for the remaining requests to
wait for that grace period to complete. However, that is the topic of
the next section.
Expand Down Expand Up @@ -405,7 +405,7 @@ Use of Workqueues
In earlier implementations, the task requesting the expedited grace
period also drove it to completion. This straightforward approach had
the disadvantage of needing to account for POSIX signals sent to user
tasks, so more recent implemementations use the Linux kernel's
tasks, so more recent implementations use the Linux kernel's
workqueues (see Documentation/core-api/workqueue.rst).

The requesting task still does counter snapshotting and funnel-lock
Expand Down Expand Up @@ -465,7 +465,7 @@ corresponding disadvantage that workqueues cannot be used until they are
initialized, which does not happen until some time after the scheduler
spawns the first task. Given that there are parts of the kernel that
really do want to execute grace periods during this mid-boot “dead
zone”, expedited grace periods must do something else during thie time.
zone”, expedited grace periods must do something else during this time.

What they do is to fall back to the old practice of requiring that the
requesting task drive the expedited grace period, as was the case before
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ an ``atomic_add_return()`` of zero) to detect idle CPUs.
+-----------------------------------------------------------------------+

The approach must be extended to handle one final case, that of waking a
task blocked in ``synchronize_rcu()``. This task might be affinitied to
task blocked in ``synchronize_rcu()``. This task might be affined to
a CPU that is not yet aware that the grace period has ended, and thus
might not yet be subject to the grace period's memory ordering.
Therefore, there is an ``smp_mb()`` after the return from
Expand Down
10 changes: 5 additions & 5 deletions Documentation/RCU/RTFP.txt
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ work looked at debugging uses of RCU [Seyster:2011:RFA:2075416.2075425].
In 2012, Josh Triplett received his Ph.D. with his dissertation
covering RCU-protected resizable hash tables and the relationship
between memory barriers and read-side traversal order: If the updater
is making changes in the opposite direction from the read-side traveral
is making changes in the opposite direction from the read-side traversal
order, the updater need only execute a memory-barrier instruction,
but if in the same direction, the updater needs to wait for a grace
period between the individual updates [JoshTriplettPhD]. Also in 2012,
Expand Down Expand Up @@ -1245,7 +1245,7 @@ Oregon Health and Sciences University"
[Viewed September 5, 2005]"
,annotation={
First posting showing how RCU can be safely adapted for
preemptable RCU read side critical sections.
preemptible RCU read side critical sections.
}
}

Expand Down Expand Up @@ -1888,7 +1888,7 @@ Revised:
\url{https://lore.kernel.org/r/20070910183004.GA3299@linux.vnet.ibm.com}
[Viewed October 25, 2007]"
,annotation={
Final patch for preemptable RCU to -rt. (Later patches were
Final patch for preemptible RCU to -rt. (Later patches were
to mainline, eventually incorporated.)
}
}
Expand Down Expand Up @@ -2275,7 +2275,7 @@ lot of {Linux} into your technology!!!"
\url{https://lore.kernel.org/r/20090724001429.GA17374@linux.vnet.ibm.com}
[Viewed August 15, 2009]"
,annotation={
First posting of simple and fast preemptable RCU.
First posting of simple and fast preemptible RCU.
}
}

Expand Down Expand Up @@ -2639,7 +2639,7 @@ lot of {Linux} into your technology!!!"
RCU-protected hash tables, barriers vs. read-side traversal order.
.
If the updater is making changes in the opposite direction from
the read-side traveral order, the updater need only execute a
the read-side traversal order, the updater need only execute a
memory-barrier instruction, but if in the same direction, the
updater needs to wait for a grace period between the individual
updates.
Expand Down
4 changes: 2 additions & 2 deletions Documentation/RCU/UP.rst
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ UP systems, including PREEMPT SMP builds running on UP systems.

Quick Quiz #3:
Why can't synchronize_rcu() return immediately on UP systems running
preemptable RCU?
preemptible RCU?

.. _answer_quick_quiz_up:

Expand Down Expand Up @@ -143,7 +143,7 @@ Answer to Quick Quiz #2:

Answer to Quick Quiz #3:
Why can't synchronize_rcu() return immediately on UP systems
running preemptable RCU?
running preemptible RCU?

Because some other task might have been preempted in the middle
of an RCU read-side critical section. If synchronize_rcu()
Expand Down
2 changes: 1 addition & 1 deletion Documentation/RCU/checklist.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ over a rather long period of time, but improvements are always welcome!
can serve as rcu_read_lock_sched(), but is less readable and
prevents lockdep from detecting locking issues.

Please not that you *cannot* rely on code known to be built
Please note that you *cannot* rely on code known to be built
only in non-preemptible kernels. Such code can and will break,
especially in kernels built with CONFIG_PREEMPT_COUNT=y.

Expand Down
2 changes: 1 addition & 1 deletion Documentation/RCU/lockdep.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ checking of rcu_dereference() primitives:
rcu_access_pointer(p):
Return the value of the pointer and omit all barriers,
but retain the compiler constraints that prevent duplicating
or coalescsing. This is useful when testing the
or coalescing. This is useful when testing the
value of the pointer itself, for example, against NULL.

The rcu_dereference_check() check expression can be any boolean
Expand Down
4 changes: 2 additions & 2 deletions Documentation/RCU/torture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ Kernel boot arguments can also be supplied, for example, to control
rcutorture's module parameters. For example, to test a change to RCU's
CPU stall-warning code, use "--bootargs 'rcutorture.stall_cpu=30'".
This will of course result in the scripting reporting a failure, namely
the resuling RCU CPU stall warning. As noted above, reducing memory may
the resulting RCU CPU stall warning. As noted above, reducing memory may
require disabling rcutorture's callback-flooding tests::

kvm.sh --cpus 448 --configs '56*TREE04' --memory 128M \
Expand Down Expand Up @@ -370,5 +370,5 @@ You can also re-run a previous remote run in a manner similar to kvm.sh:
tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28-remote \
--duration 24h

In this case, most of the kvm-again.sh parmeters may be supplied following
In this case, most of the kvm-again.sh parameters may be supplied following
the pathname of the old run-results directory.
6 changes: 3 additions & 3 deletions Documentation/RCU/whatisRCU.rst
Original file line number Diff line number Diff line change
Expand Up @@ -597,10 +597,10 @@ to avoid having to write your own callback::
If the occasional sleep is permitted, the single-argument form may
be used, omitting the rcu_head structure from struct foo.

kfree_rcu(old_fp);
kfree_rcu_mightsleep(old_fp);

This variant of kfree_rcu() almost never blocks, but might do so by
invoking synchronize_rcu() in response to memory-allocation failure.
This variant almost never blocks, but might do so by invoking
synchronize_rcu() in response to memory-allocation failure.

Again, see checklist.rst for additional rules governing the use of RCU.

Expand Down
6 changes: 3 additions & 3 deletions drivers/block/drbd/drbd_nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1615,7 +1615,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
drbd_send_sync_param(peer_device);
}

kvfree_rcu(old_disk_conf);
kvfree_rcu_mightsleep(old_disk_conf);
kfree(old_plan);
mod_timer(&device->request_timer, jiffies + HZ);
goto success;
Expand Down Expand Up @@ -2446,7 +2446,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)

mutex_unlock(&connection->resource->conf_update);
mutex_unlock(&connection->data.mutex);
kvfree_rcu(old_net_conf);
kvfree_rcu_mightsleep(old_net_conf);

if (connection->cstate >= C_WF_REPORT_PARAMS) {
struct drbd_peer_device *peer_device;
Expand Down Expand Up @@ -2860,7 +2860,7 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info)
new_disk_conf->disk_size = (sector_t)rs.resize_size;
rcu_assign_pointer(device->ldev->disk_conf, new_disk_conf);
mutex_unlock(&device->resource->conf_update);
kvfree_rcu(old_disk_conf);
kvfree_rcu_mightsleep(old_disk_conf);
new_disk_conf = NULL;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/block/drbd/drbd_receiver.c
Original file line number Diff line number Diff line change
Expand Up @@ -3759,7 +3759,7 @@ static int receive_protocol(struct drbd_connection *connection, struct packet_in
drbd_info(connection, "peer data-integrity-alg: %s\n",
integrity_alg[0] ? integrity_alg : "(none)");

kvfree_rcu(old_net_conf);
kvfree_rcu_mightsleep(old_net_conf);
return 0;

disconnect_rcu_unlock:
Expand Down Expand Up @@ -4127,7 +4127,7 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info

rcu_assign_pointer(device->ldev->disk_conf, new_disk_conf);
mutex_unlock(&connection->resource->conf_update);
kvfree_rcu(old_disk_conf);
kvfree_rcu_mightsleep(old_disk_conf);

drbd_info(device, "Peer sets u_size to %lu sectors (old: %lu)\n",
(unsigned long)p_usize, (unsigned long)my_usize);
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/drbd/drbd_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -2071,7 +2071,7 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
conn_free_crypto(connection);
mutex_unlock(&connection->resource->conf_update);

kvfree_rcu(old_conf);
kvfree_rcu_mightsleep(old_conf);
}

if (ns_max.susp_fen) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/misc/vmw_vmci/vmci_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ int vmci_ctx_remove_notification(u32 context_id, u32 remote_cid)
spin_unlock(&context->lock);

if (notifier)
kvfree_rcu(notifier);
kvfree_rcu_mightsleep(notifier);

vmci_ctx_put(context);

Expand Down
2 changes: 1 addition & 1 deletion drivers/misc/vmw_vmci/vmci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ int vmci_event_unsubscribe(u32 sub_id)
if (!s)
return VMCI_ERROR_NOT_FOUND;

kvfree_rcu(s);
kvfree_rcu_mightsleep(s);

return VMCI_SUCCESS;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en/tc/int_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ mlx5e_int_port_remove(struct mlx5e_tc_int_port_priv *priv,
mlx5_del_flow_rules(int_port->rx_rule);
mapping_remove(ctx, int_port->mapping);
mlx5e_int_port_metadata_free(priv, int_port->match_metadata);
kfree_rcu(int_port);
kfree_rcu_mightsleep(int_port);
priv->num_ports--;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ static int mlx5e_macsec_del_txsa(struct macsec_context *ctx)

mlx5e_macsec_cleanup_sa(macsec, tx_sa, true);
mlx5_destroy_encryption_key(macsec->mdev, tx_sa->enc_key_id);
kfree_rcu(tx_sa);
kfree_rcu_mightsleep(tx_sa);
macsec_device->tx_sa[assoc_num] = NULL;

out:
Expand Down Expand Up @@ -849,7 +849,7 @@ static void macsec_del_rxsc_ctx(struct mlx5e_macsec *macsec, struct mlx5e_macsec
xa_erase(&macsec->sc_xarray, rx_sc->sc_xarray_element->fs_id);
metadata_dst_free(rx_sc->md_dst);
kfree(rx_sc->sc_xarray_element);
kfree_rcu(rx_sc);
kfree_rcu_mightsleep(rx_sc);
}

static int mlx5e_macsec_del_rxsc(struct macsec_context *ctx)
Expand Down
2 changes: 1 addition & 1 deletion fs/ext4/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -2500,7 +2500,7 @@ static void ext4_apply_quota_options(struct fs_context *fc,
qname = rcu_replace_pointer(sbi->s_qf_names[i], qname,
lockdep_is_held(&sb->s_umount));
if (qname)
kfree_rcu(qname);
kfree_rcu_mightsleep(qname);
}
}

Expand Down
8 changes: 7 additions & 1 deletion include/linux/lockdep.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ struct held_lock {
unsigned int read:2; /* see lock_acquire() comment */
unsigned int check:1; /* see lock_acquire() comment */
unsigned int hardirqs_off:1;
unsigned int references:12; /* 32 bits */
unsigned int sync:1;
unsigned int references:11; /* 32 bits */
unsigned int pin_count;
};

Expand Down Expand Up @@ -268,6 +269,10 @@ extern void lock_acquire(struct lockdep_map *lock, unsigned int subclass,

extern void lock_release(struct lockdep_map *lock, unsigned long ip);

extern void lock_sync(struct lockdep_map *lock, unsigned int subclass,
int read, int check, struct lockdep_map *nest_lock,
unsigned long ip);

/* lock_is_held_type() returns */
#define LOCK_STATE_UNKNOWN -1
#define LOCK_STATE_NOT_HELD 0
Expand Down Expand Up @@ -554,6 +559,7 @@ do { \
#define lock_map_acquire_read(l) lock_acquire_shared_recursive(l, 0, 0, NULL, _THIS_IP_)
#define lock_map_acquire_tryread(l) lock_acquire_shared_recursive(l, 0, 1, NULL, _THIS_IP_)
#define lock_map_release(l) lock_release(l, _THIS_IP_)
#define lock_map_sync(l) lock_sync(l, 0, 0, 1, NULL, _THIS_IP_)

#ifdef CONFIG_PROVE_LOCKING
# define might_lock(lock) \
Expand Down
5 changes: 4 additions & 1 deletion include/linux/notifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ struct raw_notifier_head {

struct srcu_notifier_head {
struct mutex mutex;
#ifdef CONFIG_TREE_SRCU
struct srcu_usage srcuu;
#endif
struct srcu_struct srcu;
struct notifier_block __rcu *head;
};
Expand Down Expand Up @@ -107,7 +110,7 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
{ \
.mutex = __MUTEX_INITIALIZER(name.mutex), \
.head = NULL, \
.srcu = __SRCU_STRUCT_INIT(name.srcu, pcpu), \
.srcu = __SRCU_STRUCT_INIT(name.srcu, name.srcuu, pcpu), \
}

#define ATOMIC_NOTIFIER_HEAD(name) \
Expand Down
34 changes: 32 additions & 2 deletions include/linux/srcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,43 @@ static inline int srcu_read_lock_held(const struct srcu_struct *ssp)
return lock_is_held(&ssp->dep_map);
}

/*
* Annotations provide deadlock detection for SRCU.
*
* Similar to other lockdep annotations, except there is an additional
* srcu_lock_sync(), which is basically an empty *write*-side critical section,
* see lock_sync() for more information.
*/

/* Annotates a srcu_read_lock() */
static inline void srcu_lock_acquire(struct lockdep_map *map)
{
lock_map_acquire_read(map);
}

/* Annotates a srcu_read_lock() */
static inline void srcu_lock_release(struct lockdep_map *map)
{
lock_map_release(map);
}

/* Annotates a synchronize_srcu() */
static inline void srcu_lock_sync(struct lockdep_map *map)
{
lock_map_sync(map);
}

#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */

static inline int srcu_read_lock_held(const struct srcu_struct *ssp)
{
return 1;
}

#define srcu_lock_acquire(m) do { } while (0)
#define srcu_lock_release(m) do { } while (0)
#define srcu_lock_sync(m) do { } while (0)

#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */

#define SRCU_NMI_UNKNOWN 0x0
Expand Down Expand Up @@ -182,7 +212,7 @@ static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp)

srcu_check_nmi_safety(ssp, false);
retval = __srcu_read_lock(ssp);
rcu_lock_acquire(&(ssp)->dep_map);
srcu_lock_acquire(&(ssp)->dep_map);
return retval;
}

Expand Down Expand Up @@ -254,7 +284,7 @@ static inline void srcu_read_unlock(struct srcu_struct *ssp, int idx)
{
WARN_ON_ONCE(idx & ~0x1);
srcu_check_nmi_safety(ssp, false);
rcu_lock_release(&(ssp)->dep_map);
srcu_lock_release(&(ssp)->dep_map);
__srcu_read_unlock(ssp, idx);
}

Expand Down
6 changes: 3 additions & 3 deletions include/linux/srcutiny.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ struct srcu_struct {

void srcu_drive_gp(struct work_struct *wp);

#define __SRCU_STRUCT_INIT(name, __ignored) \
#define __SRCU_STRUCT_INIT(name, __ignored, ___ignored) \
{ \
.srcu_wq = __SWAIT_QUEUE_HEAD_INITIALIZER(name.srcu_wq), \
.srcu_cb_tail = &name.srcu_cb_head, \
Expand All @@ -44,9 +44,9 @@ void srcu_drive_gp(struct work_struct *wp);
* Tree SRCU, which needs some per-CPU data.
*/
#define DEFINE_SRCU(name) \
struct srcu_struct name = __SRCU_STRUCT_INIT(name, name)
struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name)
#define DEFINE_STATIC_SRCU(name) \
static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name)
static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name)

void synchronize_srcu(struct srcu_struct *ssp);

Expand Down
Loading

0 comments on commit 8ae9985

Please sign in to comment.