android_kernel_sony_sdm845/kernel/time/timer_list.c
jianzhou b62aeea0ec Merge android-4.9.149 (ed0b11d) into msm-4.9
*  refs/heads/tmp-ed0b11d:
  Linux 4.9.149
  spi: bcm2835: Unbreak the build of esoteric configs
  tpm: tpm_i2c_nuvoton: use correct command duration for TPM 2.x
  rtc: m41t80: Correct alarm month range with RTC reads
  arm64: KVM: Avoid setting the upper 32 bits of VTCR_EL2 to 1
  x86/kvm/vmx: do not use vm-exit instruction length for fast MMIO when running nested
  CIFS: Fix error mapping for SMB2_LOCK command which caused OFD lock problem
  MIPS: OCTEON: mark RGMII interface disabled on OCTEON III
  MIPS: Align kernel load address to 64KB
  MIPS: Ensure pmd_present() returns false after pmd_mknotpresent()
  media: v4l2-tpg: array index could become negative
  media: vivid: free bitmap_cap when updating std/timings/etc.
  serial: uartps: Fix interrupt mask issue to handle the RX interrupts properly
  f2fs: fix validation of the block count in sanity_check_raw_super
  cdc-acm: fix abnormal DATA RX issue for Mediatek Preloader.
  clk: rockchip: fix typo in rk3188 spdif_frac parent
  spi: bcm2835: Avoid finishing transfer prematurely in IRQ mode
  spi: bcm2835: Fix book-keeping of DMA termination
  spi: bcm2835: Fix race on DMA termination
  ext4: force inode writes when nfsd calls commit_metadata()
  ext4: include terminating u32 in size of xattr entries when expanding inodes
  ext4: fix EXT4_IOC_GROUP_ADD ioctl
  ext4: missing unlock/put_page() in ext4_try_to_write_inline_data()
  ext4: fix possible use after free in ext4_quota_enable
  perf pmu: Suppress potential format-truncation warning
  platform-msi: Free descriptors in platform_msi_domain_free()
  KVM: x86: Use jmp to invoke kvm_spurious_fault() from .fixup
  Input: elan_i2c - add ACPI ID for touchpad in ASUS Aspire F5-573G
  qmi_wwan: apply SET_DTR quirk to the SIMCOM shared device ID
  staging: wilc1000: fix missing read_write setting when reading data
  usb: r8a66597: Fix a possible concurrency use-after-free bug in r8a66597_endpoint_disable()
  USB: serial: option: add Fibocom NL678 series
  USB: serial: pl2303: add ids for Hewlett-Packard HP POS pole displays
  ALSA: hda/tegra: clear pending irq handlers
  ALSA: hda: add mute LED support for HP EliteBook 840 G4
  mtd: atmel-quadspi: disallow building on ebsa110
  ALSA: emux: Fix potential Spectre v1 vulnerabilities
  ALSA: pcm: Fix potential Spectre v1 vulnerability
  ALSA: emu10k1: Fix potential Spectre v1 vulnerabilities
  ALSA: rme9652: Fix potential Spectre v1 vulnerability
  ptr_ring: wrap back ->producer in __ptr_ring_swap_queue()
  sock: Make sock->sk_stamp thread-safe
  net/mlx5: Typo fix in del_sw_hw_rule
  net/mlx5e: Remove the false indication of software timestamping support
  gro_cell: add napi_disable in gro_cells_destroy
  tipc: compare remote and local protocols in tipc_udp_enable()
  tipc: use lock_sock() in tipc_sk_reinit()
  xen/netfront: tolerate frags with no data
  VSOCK: Send reset control packet when socket is partially bound
  vhost: make sure used idx is seen before log in vhost_add_used_n()
  tipc: fix a double kfree_skb()
  sctp: initialize sin6_flowinfo for ipv6 addrs in sctp_inet6addr_event
  packet: validate address length if non-zero
  packet: validate address length
  net/wan: fix a double free in x25_asy_open_tty()
  netrom: fix locking in nr_find_socket()
  net: phy: Fix the issue that netif always links up after resuming
  net: ipv4: do not handle duplicate fragments as overlapping
  isdn: fix kernel-infoleak in capi_unlocked_ioctl
  ipv6: tunnels: fix two use-after-free
  ipv6: explicitly initialize udp6_addr in udp_sock_create6()
  ieee802154: lowpan_header_create check must check daddr
  ibmveth: fix DMA unmap error in ibmveth_xmit_start error path
  ax25: fix a use-after-free in ax25_fillin_cb()
  ipv4: Fix potential Spectre v1 vulnerability
  ip6mr: Fix potential Spectre v1 vulnerability
  NFC: nxp-nci: Include unaligned.h instead of access_ok.h
  UPSTREAM: mm: /proc/pid/smaps_rollup: fix NULL pointer deref in smaps_pte_range()
  BACKPORT: fs/proc/task_mmu.c: fix Locked field in /proc/pid/smaps*
  BACKPORT: mm: add /proc/pid/smaps_rollup
  ANDROID: cuttlefish_defconfig: Enable VIRTIO_INPUT
  Linux 4.9.148
  drm/ioctl: Fix Spectre v1 vulnerabilities
  proc/sysctl: don't return ENOMEM on lookup when a table is unregistering
  panic: avoid deadlocks in re-entrant console drivers
  ubifs: Handle re-linking of inodes correctly while recovery
  x86/fpu: Disable bottom halves while loading FPU registers
  x86/mtrr: Don't copy uninitialized gentry fields back to userspace
  Drivers: hv: vmbus: Return -EINVAL for the sys files for unopened channels
  gpio: max7301: fix driver for use with CONFIG_VMAP_STACK
  mmc: omap_hsmmc: fix DMA API warning
  mmc: core: Use a minimum 1600ms timeout when enabling CACHE ctrl
  mmc: core: Allow BKOPS and CACHE ctrl even if no HPI support
  mmc: core: Reset HPI enabled state during re-init and in case of errors
  USB: serial: option: add Telit LN940 series
  USB: serial: option: add Fibocom NL668 series
  USB: serial: option: add Simcom SIM7500/SIM7600 (MBIM mode)
  USB: serial: option: add HP lt4132
  USB: serial: option: add GosunCn ZTE WeLink ME3630
  xhci: Don't prevent USB2 bus suspend in state check intended for USB3 only
  USB: hso: Fix OOB memory access in hso_probe/hso_get_config_data
  ib_srpt: Fix a use-after-free in __srpt_close_all_ch()
  block: fix infinite loop if the device loses discard capability
  block: break discard submissions into the user defined size
  Linux 4.9.147
  rtc: snvs: Add timeouts to avoid kernel lockups
  rtc: snvs: add a missing write sync
  nvmet-rdma: fix response use after free
  i2c: scmi: Fix probe error on devices with an empty SMB0001 ACPI device node
  i2c: axxia: properly handle master timeout
  vhost/vsock: fix reset orphans race with close timeout
  cifs: In Kconfig CONFIG_CIFS_POSIX needs depends on legacy (insecure cifs)
  drm/ast: Fix connector leak during driver unload
  ethernet: fman: fix wrong of_node_put() in probe function
  ARM: 8815/1: V7M: align v7m_dma_inv_range() with v7 counterpart
  ARM: 8814/1: mm: improve/fix ARM v7_dma_inv_range() unaligned address handling
  bpf: check pending signals while verifying programs
  net/mlx4_en: Fix build break when CONFIG_INET is off
  mv88e6060: disable hardware level MAC learning
  libata: whitelist all SAMSUNG MZ7KM* solid-state disks
  Input: omap-keypad - fix keyboard debounce configuration
  clk: mmp: Off by one in mmp_clk_add()
  clk: mvebu: Off by one bugs in cp110_of_clk_get()
  ide: pmac: add of_node_put()
  drivers/tty: add missing of_node_put()
  drivers/sbus/char: add of_node_put()
  sbus: char: add of_node_put()
  SUNRPC: Fix a potential race in xprt_connect()
  nfs: don't dirty kernel pages read by direct-io
  bonding: fix 802.3ad state sent to partner when unbinding slave
  ARC: io.h: Implement reads{x}()/writes{x}()
  drm/msm: Grab a vblank reference when waiting for commit_done
  x86/earlyprintk/efi: Fix infinite loop on some screen widths
  scsi: vmw_pscsi: Rearrange code to avoid multiple calls to free_irq during unload
  scsi: libiscsi: Fix NULL pointer dereference in iscsi_eh_session_reset
  mac80211_hwsim: fix module init error paths for netlink
  locking/qspinlock: Fix build for anonymous union in older GCC compilers
  locking/qspinlock, x86: Provide liveness guarantee
  locking/qspinlock/x86: Increase _Q_PENDING_LOOPS upper bound
  locking/qspinlock: Re-order code
  locking/qspinlock: Kill cmpxchg() loop when claiming lock from head of queue
  locking/qspinlock: Remove duplicate clear_pending() function from PV code
  locking/qspinlock: Remove unbounded cmpxchg() loop from locking slowpath
  locking/qspinlock: Merge 'struct __qspinlock' into 'struct qspinlock'
  locking/qspinlock: Bound spinning on pending->locked transition in slowpath
  locking/qspinlock: Ensure node is initialised before updating prev->next
  locking: Remove smp_read_barrier_depends() from queued_spin_lock_slowpath()
  IB/hfi1: Remove race conditions in user_sdma send path
  mac80211: Fix condition validating WMM IE
  mac80211: don't WARN on bad WMM parameters from buggy APs
  drm/i915/execlists: Apply a full mb before execution for Braswell
  Revert "drm/rockchip: Allow driver to be shutdown on reboot/kexec"
  powerpc/msi: Fix NULL pointer access in teardown code
  tracing: Fix memory leak of instance function hash filters
  tracing: Fix memory leak in set_trigger_filter()
  ARM: mmp/mmp2: fix cpu_is_mmp2() on mmp2-dt
  MMC: OMAP: fix broken MMC on OMAP15XX/OMAP5910/OMAP310
  aio: fix spectre gadget in lookup_ioctx
  pinctrl: sunxi: a83t: Fix IRQ offset typo for PH11
  timer/debug: Change /proc/timer_list from 0444 to 0400
  lib/interval_tree_test.c: allow users to limit scope of endpoint
  lib/rbtree-test: lower default params
  lib/rbtree_test.c: make input module parameters
  lib/interval_tree_test.c: allow full tree search
  lib/interval_tree_test.c: make test options module parameters
  signal: Introduce COMPAT_SIGMINSTKSZ for use in compat_sys_sigaltstack
  ANDROID: Revert fs/squashfs back to linux-4.9.y
  BACKPORT, FROMGIT: dm verity: log the hash algorithm implementation
  BACKPORT, FROMGIT: dm crypt: log the encryption algorithm implementation
  Linux 4.9.146
  staging: speakup: Replace strncpy with memcpy
  pstore: Convert console write to use ->write_buf
  ocfs2: fix potential use after free
  debugobjects: avoid recursive calls with kmemleak
  hfsplus: do not free node before using
  hfs: do not free node before using
  ocfs2: fix deadlock caused by ocfs2_defrag_extent()
  fscache, cachefiles: remove redundant variable 'cache'
  fscache: fix race between enablement and dropping of object
  xen: xlate_mmu: add missing header to fix 'W=1' warning
  drm/ast: fixed reading monitor EDID not stable issue
  net: hisilicon: remove unexpected free_netdev
  ixgbe: recognize 1000BaseLX SFP modules as 1Gbps
  igb: fix uninitialized variables
  cachefiles: Fix page leak in cachefiles_read_backing_file while vmscan is active
  net: thunderx: fix NULL pointer dereference in nic_remove
  x86/kvm/vmx: fix old-style function declaration
  KVM: x86: fix empty-body warnings
  USB: omap_udc: fix USB gadget functionality on Palm Tungsten E
  USB: omap_udc: fix omap_udc_start() on 15xx machines
  USB: omap_udc: fix crashes on probe error and module removal
  USB: omap_udc: use devm_request_irq()
  ipvs: call ip_vs_dst_notifier earlier than ipv6_dev_notf
  bpf: fix check of allowed specifiers in bpf_trace_printk
  exportfs: do not read dentry after free
  ASoC: omap-dmic: Add pm_qos handling to avoid overruns with CPU_IDLE
  ASoC: omap-mcpdm: Add pm_qos handling to avoid under/overruns with CPU_IDLE
  RDMA/mlx5: Fix fence type for IB_WR_LOCAL_INV WR
  Btrfs: send, fix infinite loop due to directory rename dependencies
  objtool: Fix segfault in .cold detection with -ffunction-sections
  objtool: Fix double-free in .cold detection error path
  hwmon: (w83795) temp4_type has writable permission
  ASoC: dapm: Recalculate audio map forcely when card instantiated
  ASoC: omap-abe-twl6040: Fix missing audio card caused by deferred probing
  hwmon: (ina2xx) Fix current value calculation
  s390/cpum_cf: Reject request for sampling in event initialization
  selftests: add script to stress-test nft packet path vs. control plane
  sysv: return 'err' instead of 0 in __sysv_write_inode
  ARM: OMAP1: ams-delta: Fix possible use of uninitialized field
  ARM: dts: logicpd-somlv: Fix interrupt on mmc3_dat1
  ARM: OMAP2+: prm44xx: Fix section annotation on omap44xx_prm_enable_io_wakeup
  neighbour: Avoid writing before skb->head in neigh_hh_output()
  tun: forbid iface creation with rtnl ops
  tcp: fix NULL ref in tail loss probe
  rtnetlink: ndo_dflt_fdb_dump() only work for ARPHRD_ETHER devices
  net: Prevent invalid access to skb->prev in __qdisc_drop_all
  net: phy: don't allow __set_phy_supported to add unsupported modes
  net/mlx4_core: Correctly set PFC param if global pause is turned off.
  net: 8139cp: fix a BUG triggered by changing mtu with network traffic
  ipv6: Check available headroom in ip6_xmit() even without options
  Makefile: Properly resolve conflict from 4.9.145
  ANDROID: cuttlefish_defconfig: Enable CONFIG_CRYPTO_ADIANTUM
  UPSTREAM: dm crypt: don't decrease device limits
  BACKPORT: dm crypt: allow unaligned bv_offset
  BACKPORT: dm crypt: reject sector_size feature if device length is not aligned to it
  BACKPORT: dm crypt: use shifts instead of sector_div
  BACKPORT: dm crypt: optionally support larger encryption sector size
  BACKPORT, FROMGIT: fscrypt: add Adiantum support
  BACKPORT, FROMGIT: crypto: adiantum - add Adiantum support
  FROMGIT: crypto: arm/nhpoly1305 - add NEON-accelerated NHPoly1305
  BACKPORT, FROMGIT: crypto: nhpoly1305 - add NHPoly1305 support
  FROMGIT: crypto: poly1305 - add Poly1305 core API
  FROMGIT: crypto: poly1305 - use structures for key and accumulator
  BACKPORT, FROMGIT: crypto: arm/chacha - add XChaCha12 support
  BACKPORT, FROMGIT: crypto: arm/chacha20 - refactor to allow varying number of rounds
  BACKPORT, FROMGIT: crypto: arm/chacha20 - add XChaCha20 support
  BACKPORT, FROMGIT: crypto: arm/chacha20 - limit the preemption-disabled section
  BACKPORT, FROMGIT: crypto: chacha - add XChaCha12 support
  BACKPORT, FROMGIT: crypto: chacha20-generic - refactor to allow varying number of rounds
  BACKPORT, FROMGIT: crypto: chacha20-generic - add XChaCha20 support
  FROMGIT: crypto: chacha20-generic - add HChaCha20 library function
  FROMGIT: crypto: arm/aes - add some hardening against cache-timing attacks
  UPSTREAM: crypto: arm/aes-cipher - move S-box to .rodata section
  UPSTREAM: crypto: arm/aes - avoid expanded lookup tables in the final round
  UPSTREAM: crypto: arm/aes - avoid reserved 'tt' mnemonic in asm code
  BACKPORT: crypto: arm/aes - replace scalar AES cipher
  UPSTREAM: crypto: poly1305 - use unaligned access macros to output digest
  UPSTREAM: crypto: poly1305 - Use unaligned access where required
  UPSTREAM: crypto: arm/chacha20 - faster 8-bit rotations and other optimizations
  UPSTREAM: crypto: arm/chacha20 - always use vrev for 16-bit rotates
  BACKPORT: crypto: arm/chacha20 - implement NEON version based on SSE3 code
  BACKPORT: crypto: chacha20 - Fix chacha20_block() keystream alignment (again)
  UPSTREAM: crypto: chacha20 - use rol32() macro from bitops.h
  BACKPORT: crypto: chacha20 - Fix keystream alignment for chacha20_block()
  UPSTREAM: crypto: chacha20 - Use unaligned access macros when loading key and IV
  UPSTREAM: crypto: chacha20 - Fix unaligned access when loading constants
  UPSTREAM: crypto: testmgr - fix overlap in chunked tests again
  UPSTREAM: crypto: testmgr - avoid overlap in chunked tests
  ANDROID: cuttlefish_defconfig: Enable VIRT_WIFI
  FROMGIT, BACKPORT: mac80211-next: rtnetlink wifi simulation device
  ANDROID: cuttlefish_defconfig: Enable CONFIG_ARM64_LSE_ATOMICS
  ANDROID: Move from clang r328903 to r346389b.
  ANDROID: arm64 defconfig / build config for cuttlefish

Conflicts:
	drivers/char/random.c
	drivers/md/dm-crypt.c
	drivers/mmc/core/mmc.c
	drivers/net/wireless/Kconfig
	drivers/net/wireless/Makefile
	fs/crypto/fscrypt_private.h
	fs/crypto/keyinfo.c
	include/uapi/linux/fs.h

Change-Id: I3f7617ac7ab346b0650757e25ef3e7daf4d97a1e
Signed-off-by: jianzhou <jianzhou@codeaurora.org>
2019-02-12 11:18:51 +08:00

397 lines
9.4 KiB
C

/*
* kernel/time/timer_list.c
*
* List pending timers
*
* Copyright(C) 2006, Red Hat, Inc., Ingo Molnar
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/proc_fs.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/kallsyms.h>
#include <linux/nmi.h>
#include <asm/uaccess.h>
#include "tick-internal.h"
struct timer_list_iter {
int cpu;
bool second_pass;
u64 now;
};
typedef void (*print_fn_t)(struct seq_file *m, unsigned int *classes);
/*
* This allows printing both to /proc/timer_list and
* to the console (on SysRq-Q):
*/
__printf(2, 3)
static void SEQ_printf(struct seq_file *m, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
if (m)
seq_vprintf(m, fmt, args);
else
vprintk(fmt, args);
va_end(args);
}
static void print_name_offset(struct seq_file *m, void *sym)
{
char symname[KSYM_NAME_LEN];
if (lookup_symbol_name((unsigned long)sym, symname) < 0)
SEQ_printf(m, "<%pK>", sym);
else
SEQ_printf(m, "%s", symname);
}
static void
print_timer(struct seq_file *m, struct hrtimer *taddr, struct hrtimer *timer,
int idx, u64 now)
{
SEQ_printf(m, " #%d: ", idx);
print_name_offset(m, taddr);
SEQ_printf(m, ", ");
print_name_offset(m, timer->function);
SEQ_printf(m, ", S:%02x", timer->state);
SEQ_printf(m, "\n");
SEQ_printf(m, " # expires at %Lu-%Lu nsecs [in %Ld to %Ld nsecs]\n",
(unsigned long long)ktime_to_ns(hrtimer_get_softexpires(timer)),
(unsigned long long)ktime_to_ns(hrtimer_get_expires(timer)),
(long long)(ktime_to_ns(hrtimer_get_softexpires(timer)) - now),
(long long)(ktime_to_ns(hrtimer_get_expires(timer)) - now));
}
static void
print_active_timers(struct seq_file *m, struct hrtimer_clock_base *base,
u64 now)
{
struct hrtimer *timer, tmp;
unsigned long next = 0, i;
struct timerqueue_node *curr;
unsigned long flags;
next_one:
i = 0;
touch_nmi_watchdog();
raw_spin_lock_irqsave(&base->cpu_base->lock, flags);
curr = timerqueue_getnext(&base->active);
/*
* Crude but we have to do this O(N*N) thing, because
* we have to unlock the base when printing:
*/
while (curr && i < next) {
curr = timerqueue_iterate_next(curr);
i++;
}
if (curr) {
timer = container_of(curr, struct hrtimer, node);
tmp = *timer;
raw_spin_unlock_irqrestore(&base->cpu_base->lock, flags);
print_timer(m, timer, &tmp, i, now);
next++;
goto next_one;
}
raw_spin_unlock_irqrestore(&base->cpu_base->lock, flags);
}
static void
print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now)
{
SEQ_printf(m, " .base: %pK\n", base);
SEQ_printf(m, " .index: %d\n", base->index);
SEQ_printf(m, " .resolution: %u nsecs\n", (unsigned) hrtimer_resolution);
SEQ_printf(m, " .get_time: ");
print_name_offset(m, base->get_time);
SEQ_printf(m, "\n");
#ifdef CONFIG_HIGH_RES_TIMERS
SEQ_printf(m, " .offset: %Lu nsecs\n",
(unsigned long long) ktime_to_ns(base->offset));
#endif
SEQ_printf(m, "active timers:\n");
print_active_timers(m, base, now + ktime_to_ns(base->offset));
}
static void print_cpu(struct seq_file *m, int cpu, u64 now)
{
struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
int i;
SEQ_printf(m, "cpu: %d\n", cpu);
for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
SEQ_printf(m, " clock %d:\n", i);
print_base(m, cpu_base->clock_base + i, now);
}
#define P(x) \
SEQ_printf(m, " .%-15s: %Lu\n", #x, \
(unsigned long long)(cpu_base->x))
#define P_ns(x) \
SEQ_printf(m, " .%-15s: %Lu nsecs\n", #x, \
(unsigned long long)(ktime_to_ns(cpu_base->x)))
#ifdef CONFIG_HIGH_RES_TIMERS
P_ns(expires_next);
P(hres_active);
P(nr_events);
P(nr_retries);
P(nr_hangs);
P(max_hang_time);
#endif
#undef P
#undef P_ns
#ifdef CONFIG_TICK_ONESHOT
# define P(x) \
SEQ_printf(m, " .%-15s: %Lu\n", #x, \
(unsigned long long)(ts->x))
# define P_ns(x) \
SEQ_printf(m, " .%-15s: %Lu nsecs\n", #x, \
(unsigned long long)(ktime_to_ns(ts->x)))
{
struct tick_sched *ts = tick_get_tick_sched(cpu);
P(nohz_mode);
P_ns(last_tick);
P(tick_stopped);
P(idle_jiffies);
P(idle_calls);
P(idle_sleeps);
P_ns(idle_entrytime);
P_ns(idle_waketime);
P_ns(idle_exittime);
P_ns(idle_sleeptime);
P_ns(iowait_sleeptime);
P(last_jiffies);
P(next_timer);
P_ns(idle_expires);
SEQ_printf(m, "jiffies: %Lu\n",
(unsigned long long)jiffies);
}
#endif
#undef P
#undef P_ns
SEQ_printf(m, "\n");
}
#ifdef CONFIG_GENERIC_CLOCKEVENTS
static void
print_tickdevice(struct seq_file *m, struct tick_device *td, int cpu)
{
struct clock_event_device *dev = td->evtdev;
touch_nmi_watchdog();
SEQ_printf(m, "Tick Device: mode: %d\n", td->mode);
if (cpu < 0)
SEQ_printf(m, "Broadcast device\n");
else
SEQ_printf(m, "Per CPU device: %d\n", cpu);
SEQ_printf(m, "Clock Event Device: ");
if (!dev) {
SEQ_printf(m, "<NULL>\n");
return;
}
SEQ_printf(m, "%s\n", dev->name);
SEQ_printf(m, " max_delta_ns: %llu\n",
(unsigned long long) dev->max_delta_ns);
SEQ_printf(m, " min_delta_ns: %llu\n",
(unsigned long long) dev->min_delta_ns);
SEQ_printf(m, " mult: %u\n", dev->mult);
SEQ_printf(m, " shift: %u\n", dev->shift);
SEQ_printf(m, " mode: %d\n", clockevent_get_state(dev));
SEQ_printf(m, " next_event: %Ld nsecs\n",
(unsigned long long) ktime_to_ns(dev->next_event));
SEQ_printf(m, " set_next_event: ");
print_name_offset(m, dev->set_next_event);
SEQ_printf(m, "\n");
if (dev->set_state_shutdown) {
SEQ_printf(m, " shutdown: ");
print_name_offset(m, dev->set_state_shutdown);
SEQ_printf(m, "\n");
}
if (dev->set_state_periodic) {
SEQ_printf(m, " periodic: ");
print_name_offset(m, dev->set_state_periodic);
SEQ_printf(m, "\n");
}
if (dev->set_state_oneshot) {
SEQ_printf(m, " oneshot: ");
print_name_offset(m, dev->set_state_oneshot);
SEQ_printf(m, "\n");
}
if (dev->set_state_oneshot_stopped) {
SEQ_printf(m, " oneshot stopped: ");
print_name_offset(m, dev->set_state_oneshot_stopped);
SEQ_printf(m, "\n");
}
if (dev->tick_resume) {
SEQ_printf(m, " resume: ");
print_name_offset(m, dev->tick_resume);
SEQ_printf(m, "\n");
}
SEQ_printf(m, " event_handler: ");
print_name_offset(m, dev->event_handler);
SEQ_printf(m, "\n");
SEQ_printf(m, " retries: %lu\n", dev->retries);
SEQ_printf(m, "\n");
}
static void timer_list_show_tickdevices_header(struct seq_file *m)
{
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
print_tickdevice(m, tick_get_broadcast_device(), -1);
SEQ_printf(m, "tick_broadcast_mask: %*pb\n",
cpumask_pr_args(tick_get_broadcast_mask()));
#ifdef CONFIG_TICK_ONESHOT
SEQ_printf(m, "tick_broadcast_oneshot_mask: %*pb\n",
cpumask_pr_args(tick_get_broadcast_oneshot_mask()));
#endif
SEQ_printf(m, "\n");
#endif
}
#endif
static inline void timer_list_header(struct seq_file *m, u64 now)
{
SEQ_printf(m, "Timer List Version: v0.8\n");
SEQ_printf(m, "HRTIMER_MAX_CLOCK_BASES: %d\n", HRTIMER_MAX_CLOCK_BASES);
SEQ_printf(m, "now at %Ld nsecs\n", (unsigned long long)now);
SEQ_printf(m, "\n");
}
static int timer_list_show(struct seq_file *m, void *v)
{
struct timer_list_iter *iter = v;
if (iter->cpu == -1 && !iter->second_pass)
timer_list_header(m, iter->now);
else if (!iter->second_pass)
print_cpu(m, iter->cpu, iter->now);
#ifdef CONFIG_GENERIC_CLOCKEVENTS
else if (iter->cpu == -1 && iter->second_pass)
timer_list_show_tickdevices_header(m);
else
print_tickdevice(m, tick_get_device(iter->cpu), iter->cpu);
#endif
return 0;
}
void sysrq_timer_list_show(void)
{
u64 now = ktime_to_ns(ktime_get());
int cpu;
timer_list_header(NULL, now);
for_each_online_cpu(cpu)
print_cpu(NULL, cpu, now);
#ifdef CONFIG_GENERIC_CLOCKEVENTS
timer_list_show_tickdevices_header(NULL);
for_each_online_cpu(cpu)
print_tickdevice(NULL, tick_get_device(cpu), cpu);
#endif
return;
}
static void *move_iter(struct timer_list_iter *iter, loff_t offset)
{
for (; offset; offset--) {
iter->cpu = cpumask_next(iter->cpu, cpu_online_mask);
if (iter->cpu >= nr_cpu_ids) {
#ifdef CONFIG_GENERIC_CLOCKEVENTS
if (!iter->second_pass) {
iter->cpu = -1;
iter->second_pass = true;
} else
return NULL;
#else
return NULL;
#endif
}
}
return iter;
}
static void *timer_list_start(struct seq_file *file, loff_t *offset)
{
struct timer_list_iter *iter = file->private;
if (!*offset)
iter->now = ktime_to_ns(ktime_get());
iter->cpu = -1;
iter->second_pass = false;
return move_iter(iter, *offset);
}
static void *timer_list_next(struct seq_file *file, void *v, loff_t *offset)
{
struct timer_list_iter *iter = file->private;
++*offset;
return move_iter(iter, 1);
}
static void timer_list_stop(struct seq_file *seq, void *v)
{
}
static const struct seq_operations timer_list_sops = {
.start = timer_list_start,
.next = timer_list_next,
.stop = timer_list_stop,
.show = timer_list_show,
};
static int timer_list_open(struct inode *inode, struct file *filp)
{
return seq_open_private(filp, &timer_list_sops,
sizeof(struct timer_list_iter));
}
static const struct file_operations timer_list_fops = {
.open = timer_list_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_private,
};
static int __init init_timer_list_procfs(void)
{
struct proc_dir_entry *pe;
pe = proc_create("timer_list", 0400, NULL, &timer_list_fops);
if (!pe)
return -ENOMEM;
return 0;
}
__initcall(init_timer_list_procfs);