Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dfb4357d authored by Kees Cook's avatar Kees Cook Committed by Thomas Gleixner
Browse files

time: Remove CONFIG_TIMER_STATS



Currently CONFIG_TIMER_STATS exposes process information across namespaces:

kernel/time/timer_list.c print_timer():

        SEQ_printf(m, ", %s/%d", tmp, timer->start_pid);

/proc/timer_list:

 #11: <0000000000000000>, hrtimer_wakeup, S:01, do_nanosleep, cron/2570

Given that the tracer can give the same information, this patch entirely
removes CONFIG_TIMER_STATS.

Suggested-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Acked-by: default avatarJohn Stultz <john.stultz@linaro.org>
Cc: Nicolas Pitre <nicolas.pitre@linaro.org>
Cc: linux-doc@vger.kernel.org
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Xing Gao <xgao01@email.wm.edu>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Jessica Frazelle <me@jessfraz.com>
Cc: kernel-hardening@lists.openwall.com
Cc: Nicolas Iooss <nicolas.iooss_linux@m4x.org>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Michal Marek <mmarek@suse.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Olof Johansson <olof@lixom.net>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-api@vger.kernel.org
Cc: Arjan van de Ven <arjan@linux.intel.com>
Link: http://lkml.kernel.org/r/20170208192659.GA32582@beast


Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent bb42ca47
Loading
Loading
Loading
Loading
+0 −73
Original line number Diff line number Diff line
timer_stats - timer usage statistics
------------------------------------

timer_stats is a debugging facility to make the timer (ab)usage in a Linux
system visible to kernel and userspace developers. If enabled in the config
but not used it has almost zero runtime overhead, and a relatively small
data structure overhead. Even if collection is enabled runtime all the
locking is per-CPU and lookup is hashed.

timer_stats should be used by kernel and userspace developers to verify that
their code does not make unduly use of timers. This helps to avoid unnecessary
wakeups, which should be avoided to optimize power consumption.

It can be enabled by CONFIG_TIMER_STATS in the "Kernel hacking" configuration
section.

timer_stats collects information about the timer events which are fired in a
Linux system over a sample period:

- the pid of the task(process) which initialized the timer
- the name of the process which initialized the timer
- the function where the timer was initialized
- the callback function which is associated to the timer
- the number of events (callbacks)

timer_stats adds an entry to /proc: /proc/timer_stats

This entry is used to control the statistics functionality and to read out the
sampled information.

The timer_stats functionality is inactive on bootup.

To activate a sample period issue:
# echo 1 >/proc/timer_stats

To stop a sample period issue:
# echo 0 >/proc/timer_stats

The statistics can be retrieved by:
# cat /proc/timer_stats

While sampling is enabled, each readout from /proc/timer_stats will see
newly updated statistics. Once sampling is disabled, the sampled information
is kept until a new sample period is started. This allows multiple readouts.

Sample output of /proc/timer_stats:

Timerstats sample period: 3.888770 s
  12,     0 swapper          hrtimer_stop_sched_tick (hrtimer_sched_tick)
  15,     1 swapper          hcd_submit_urb (rh_timer_func)
   4,   959 kedac            schedule_timeout (process_timeout)
   1,     0 swapper          page_writeback_init (wb_timer_fn)
  28,     0 swapper          hrtimer_stop_sched_tick (hrtimer_sched_tick)
  22,  2948 IRQ 4            tty_flip_buffer_push (delayed_work_timer_fn)
   3,  3100 bash             schedule_timeout (process_timeout)
   1,     1 swapper          queue_delayed_work_on (delayed_work_timer_fn)
   1,     1 swapper          queue_delayed_work_on (delayed_work_timer_fn)
   1,     1 swapper          neigh_table_init_no_netlink (neigh_periodic_timer)
   1,  2292 ip               __netdev_watchdog_up (dev_watchdog)
   1,    23 events/1         do_cache_clean (delayed_work_timer_fn)
90 total events, 30.0 events/sec

The first column is the number of events, the second column the pid, the third
column is the name of the process. The forth column shows the function which
initialized the timer and in parenthesis the callback function which was
executed on expiry.

    Thomas, Ingo

Added flag to indicate 'deferrable timer' in /proc/timer_stats. A deferrable
timer will appear as follows
  10D,     1 swapper          queue_delayed_work_on (delayed_work_timer_fn)
+0 −11
Original line number Diff line number Diff line
@@ -88,12 +88,6 @@ enum hrtimer_restart {
 * @base:	pointer to the timer base (per cpu and per clock)
 * @state:	state information (See bit values above)
 * @is_rel:	Set if the timer was armed relative
 * @start_pid:  timer statistics field to store the pid of the task which
 *		started the timer
 * @start_site:	timer statistics field to store the site where the timer
 *		was started
 * @start_comm: timer statistics field to store the name of the process which
 *		started the timer
 *
 * The hrtimer structure must be initialized by hrtimer_init()
 */
@@ -104,11 +98,6 @@ struct hrtimer {
	struct hrtimer_clock_base	*base;
	u8				state;
	u8				is_rel;
#ifdef CONFIG_TIMER_STATS
	int				start_pid;
	void				*start_site;
	char				start_comm[16];
#endif
};

/**
+0 −45
Original line number Diff line number Diff line
@@ -20,11 +20,6 @@ struct timer_list {
	unsigned long		data;
	u32			flags;

#ifdef CONFIG_TIMER_STATS
	int			start_pid;
	void			*start_site;
	char			start_comm[16];
#endif
#ifdef CONFIG_LOCKDEP
	struct lockdep_map	lockdep_map;
#endif
@@ -197,46 +192,6 @@ extern int mod_timer_pending(struct timer_list *timer, unsigned long expires);
 */
#define NEXT_TIMER_MAX_DELTA	((1UL << 30) - 1)

/*
 * Timer-statistics info:
 */
#ifdef CONFIG_TIMER_STATS

extern int timer_stats_active;

extern void init_timer_stats(void);

extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf,
				     void *timerf, char *comm, u32 flags);

extern void __timer_stats_timer_set_start_info(struct timer_list *timer,
					       void *addr);

static inline void timer_stats_timer_set_start_info(struct timer_list *timer)
{
	if (likely(!timer_stats_active))
		return;
	__timer_stats_timer_set_start_info(timer, __builtin_return_address(0));
}

static inline void timer_stats_timer_clear_start_info(struct timer_list *timer)
{
	timer->start_site = NULL;
}
#else
static inline void init_timer_stats(void)
{
}

static inline void timer_stats_timer_set_start_info(struct timer_list *timer)
{
}

static inline void timer_stats_timer_clear_start_info(struct timer_list *timer)
{
}
#endif

extern void add_timer(struct timer_list *timer);

extern int try_to_del_timer_sync(struct timer_list *timer);
+0 −1
Original line number Diff line number Diff line
@@ -850,7 +850,6 @@ void __kthread_queue_delayed_work(struct kthread_worker *worker,

	list_add(&work->node, &worker->delayed_work_list);
	work->worker = worker;
	timer_stats_timer_set_start_info(&dwork->timer);
	timer->expires = jiffies + delay;
	add_timer(timer);
}
+0 −1
Original line number Diff line number Diff line
@@ -15,6 +15,5 @@ ifeq ($(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST),y)
endif
obj-$(CONFIG_GENERIC_SCHED_CLOCK)		+= sched_clock.o
obj-$(CONFIG_TICK_ONESHOT)			+= tick-oneshot.o tick-sched.o
obj-$(CONFIG_TIMER_STATS)			+= timer_stats.o
obj-$(CONFIG_DEBUG_FS)				+= timekeeping_debug.o
obj-$(CONFIG_TEST_UDELAY)			+= test_udelay.o
Loading