mirror of https://gitee.com/openkylin/linux.git
rcu: Put names into TINY_RCU structures under RCU_TRACE
In order to allow event tracing to distinguish between flavors of RCU, we need those names in the relevant RCU data structures. TINY_RCU has avoided them for memory-footprint reasons, so add them only if CONFIG_RCU_TRACE=y. Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
This commit is contained in:
parent
300df91ca9
commit
e99033c5c1
10
kernel/rcu.h
10
kernel/rcu.h
|
@ -23,6 +23,12 @@
|
||||||
#ifndef __LINUX_RCU_H
|
#ifndef __LINUX_RCU_H
|
||||||
#define __LINUX_RCU_H
|
#define __LINUX_RCU_H
|
||||||
|
|
||||||
|
#ifdef CONFIG_RCU_TRACE
|
||||||
|
#define RCU_TRACE(stmt) stmt
|
||||||
|
#else /* #ifdef CONFIG_RCU_TRACE */
|
||||||
|
#define RCU_TRACE(stmt)
|
||||||
|
#endif /* #else #ifdef CONFIG_RCU_TRACE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* debug_rcu_head_queue()/debug_rcu_head_unqueue() are used internally
|
* debug_rcu_head_queue()/debug_rcu_head_unqueue() are used internally
|
||||||
* by call_rcu() and rcu callback execution, and are therefore not part of the
|
* by call_rcu() and rcu callback execution, and are therefore not part of the
|
||||||
|
@ -68,10 +74,10 @@ static inline void __rcu_reclaim(struct rcu_head *head)
|
||||||
unsigned long offset = (unsigned long)head->func;
|
unsigned long offset = (unsigned long)head->func;
|
||||||
|
|
||||||
if (__is_kfree_rcu_offset(offset)) {
|
if (__is_kfree_rcu_offset(offset)) {
|
||||||
trace_rcu_invoke_kfree_callback(head, offset);
|
RCU_TRACE(trace_rcu_invoke_kfree_callback(head, offset));
|
||||||
kfree((void *)head - offset);
|
kfree((void *)head - offset);
|
||||||
} else {
|
} else {
|
||||||
trace_rcu_invoke_callback(head);
|
RCU_TRACE(trace_rcu_invoke_callback(head));
|
||||||
head->func(head);
|
head->func(head);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,20 +38,7 @@
|
||||||
#include <linux/prefetch.h>
|
#include <linux/prefetch.h>
|
||||||
|
|
||||||
#ifdef CONFIG_RCU_TRACE
|
#ifdef CONFIG_RCU_TRACE
|
||||||
|
|
||||||
#include <trace/events/rcu.h>
|
#include <trace/events/rcu.h>
|
||||||
|
|
||||||
#else /* #ifdef CONFIG_RCU_TRACE */
|
|
||||||
|
|
||||||
/* No by-default tracing in TINY_RCU: Keep TINY_RCU tiny! */
|
|
||||||
static void trace_rcu_invoke_kfree_callback(struct rcu_head *rhp,
|
|
||||||
unsigned long offset)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
static void trace_rcu_invoke_callback(struct rcu_head *head)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* #else #ifdef CONFIG_RCU_TRACE */
|
#endif /* #else #ifdef CONFIG_RCU_TRACE */
|
||||||
|
|
||||||
#include "rcu.h"
|
#include "rcu.h"
|
||||||
|
|
|
@ -26,29 +26,26 @@
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
|
|
||||||
#ifdef CONFIG_RCU_TRACE
|
|
||||||
#define RCU_TRACE(stmt) stmt
|
|
||||||
#else /* #ifdef CONFIG_RCU_TRACE */
|
|
||||||
#define RCU_TRACE(stmt)
|
|
||||||
#endif /* #else #ifdef CONFIG_RCU_TRACE */
|
|
||||||
|
|
||||||
/* Global control variables for rcupdate callback mechanism. */
|
/* Global control variables for rcupdate callback mechanism. */
|
||||||
struct rcu_ctrlblk {
|
struct rcu_ctrlblk {
|
||||||
struct rcu_head *rcucblist; /* List of pending callbacks (CBs). */
|
struct rcu_head *rcucblist; /* List of pending callbacks (CBs). */
|
||||||
struct rcu_head **donetail; /* ->next pointer of last "done" CB. */
|
struct rcu_head **donetail; /* ->next pointer of last "done" CB. */
|
||||||
struct rcu_head **curtail; /* ->next pointer of last CB. */
|
struct rcu_head **curtail; /* ->next pointer of last CB. */
|
||||||
RCU_TRACE(long qlen); /* Number of pending CBs. */
|
RCU_TRACE(long qlen); /* Number of pending CBs. */
|
||||||
|
RCU_TRACE(char *name); /* Name of RCU type. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Definition for rcupdate control block. */
|
/* Definition for rcupdate control block. */
|
||||||
static struct rcu_ctrlblk rcu_sched_ctrlblk = {
|
static struct rcu_ctrlblk rcu_sched_ctrlblk = {
|
||||||
.donetail = &rcu_sched_ctrlblk.rcucblist,
|
.donetail = &rcu_sched_ctrlblk.rcucblist,
|
||||||
.curtail = &rcu_sched_ctrlblk.rcucblist,
|
.curtail = &rcu_sched_ctrlblk.rcucblist,
|
||||||
|
RCU_TRACE(.name = "rcu_sched")
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct rcu_ctrlblk rcu_bh_ctrlblk = {
|
static struct rcu_ctrlblk rcu_bh_ctrlblk = {
|
||||||
.donetail = &rcu_bh_ctrlblk.rcucblist,
|
.donetail = &rcu_bh_ctrlblk.rcucblist,
|
||||||
.curtail = &rcu_bh_ctrlblk.rcucblist,
|
.curtail = &rcu_bh_ctrlblk.rcucblist,
|
||||||
|
RCU_TRACE(.name = "rcu_bh")
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||||
|
@ -131,6 +128,7 @@ static struct rcu_preempt_ctrlblk rcu_preempt_ctrlblk = {
|
||||||
.rcb.curtail = &rcu_preempt_ctrlblk.rcb.rcucblist,
|
.rcb.curtail = &rcu_preempt_ctrlblk.rcb.rcucblist,
|
||||||
.nexttail = &rcu_preempt_ctrlblk.rcb.rcucblist,
|
.nexttail = &rcu_preempt_ctrlblk.rcb.rcucblist,
|
||||||
.blkd_tasks = LIST_HEAD_INIT(rcu_preempt_ctrlblk.blkd_tasks),
|
.blkd_tasks = LIST_HEAD_INIT(rcu_preempt_ctrlblk.blkd_tasks),
|
||||||
|
RCU_TRACE(.rcb.name = "rcu_preempt")
|
||||||
};
|
};
|
||||||
|
|
||||||
static int rcu_preempted_readers_exp(void);
|
static int rcu_preempted_readers_exp(void);
|
||||||
|
|
|
@ -61,7 +61,7 @@
|
||||||
static struct lock_class_key rcu_node_class[NUM_RCU_LVLS];
|
static struct lock_class_key rcu_node_class[NUM_RCU_LVLS];
|
||||||
|
|
||||||
#define RCU_STATE_INITIALIZER(structname) { \
|
#define RCU_STATE_INITIALIZER(structname) { \
|
||||||
.level = { &structname.node[0] }, \
|
.level = { &structname##_state.node[0] }, \
|
||||||
.levelcnt = { \
|
.levelcnt = { \
|
||||||
NUM_RCU_LVL_0, /* root of hierarchy. */ \
|
NUM_RCU_LVL_0, /* root of hierarchy. */ \
|
||||||
NUM_RCU_LVL_1, \
|
NUM_RCU_LVL_1, \
|
||||||
|
@ -72,17 +72,17 @@ static struct lock_class_key rcu_node_class[NUM_RCU_LVLS];
|
||||||
.signaled = RCU_GP_IDLE, \
|
.signaled = RCU_GP_IDLE, \
|
||||||
.gpnum = -300, \
|
.gpnum = -300, \
|
||||||
.completed = -300, \
|
.completed = -300, \
|
||||||
.onofflock = __RAW_SPIN_LOCK_UNLOCKED(&structname.onofflock), \
|
.onofflock = __RAW_SPIN_LOCK_UNLOCKED(&structname##_state.onofflock), \
|
||||||
.fqslock = __RAW_SPIN_LOCK_UNLOCKED(&structname.fqslock), \
|
.fqslock = __RAW_SPIN_LOCK_UNLOCKED(&structname##_state.fqslock), \
|
||||||
.n_force_qs = 0, \
|
.n_force_qs = 0, \
|
||||||
.n_force_qs_ngp = 0, \
|
.n_force_qs_ngp = 0, \
|
||||||
.name = #structname, \
|
.name = #structname, \
|
||||||
}
|
}
|
||||||
|
|
||||||
struct rcu_state rcu_sched_state = RCU_STATE_INITIALIZER(rcu_sched_state);
|
struct rcu_state rcu_sched_state = RCU_STATE_INITIALIZER(rcu_sched);
|
||||||
DEFINE_PER_CPU(struct rcu_data, rcu_sched_data);
|
DEFINE_PER_CPU(struct rcu_data, rcu_sched_data);
|
||||||
|
|
||||||
struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state);
|
struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh);
|
||||||
DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
|
DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
|
||||||
|
|
||||||
static struct rcu_state *rcu_state;
|
static struct rcu_state *rcu_state;
|
||||||
|
|
|
@ -64,7 +64,7 @@ static void __init rcu_bootup_announce_oddness(void)
|
||||||
|
|
||||||
#ifdef CONFIG_TREE_PREEMPT_RCU
|
#ifdef CONFIG_TREE_PREEMPT_RCU
|
||||||
|
|
||||||
struct rcu_state rcu_preempt_state = RCU_STATE_INITIALIZER(rcu_preempt_state);
|
struct rcu_state rcu_preempt_state = RCU_STATE_INITIALIZER(rcu_preempt);
|
||||||
DEFINE_PER_CPU(struct rcu_data, rcu_preempt_data);
|
DEFINE_PER_CPU(struct rcu_data, rcu_preempt_data);
|
||||||
static struct rcu_state *rcu_state = &rcu_preempt_state;
|
static struct rcu_state *rcu_state = &rcu_preempt_state;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue