Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer updates from Thomas Gleixner: "The time/timekeeping/timer folks deliver with this update: - Fix a reintroduced signed/unsigned issue and cleanup the whole signed/unsigned mess in the timekeeping core so this wont happen accidentaly again. - Add a new trace clock based on boot time - Prevent injection of random sleep times when PM tracing abuses the RTC for storage - Make posix timers configurable for real tiny systems - Add tracepoints for the alarm timer subsystem so timer based suspend wakeups can be instrumented - The usual pile of fixes and updates to core and drivers" * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (23 commits) timekeeping: Use mul_u64_u32_shr() instead of open coding it timekeeping: Get rid of pointless typecasts timekeeping: Make the conversion call chain consistently unsigned timekeeping_Force_unsigned_clocksource_to_nanoseconds_conversion alarmtimer: Add tracepoints for alarm timers trace: Update documentation for mono, mono_raw and boot clock trace: Add an option for boot clock as trace clock timekeeping: Add a fast and NMI safe boot clock timekeeping/clocksource_cyc2ns: Document intended range limitation timekeeping: Ignore the bogus sleep time if pm_trace is enabled selftests/timers: Fix spelling mistake "Asyncrhonous" -> "Asynchronous" clocksource/drivers/bcm2835_timer: Unmap region obtained by of_iomap clocksource/drivers/arm_arch_timer: Map frame with of_io_request_and_map() arm64: dts: rockchip: Arch counter doesn't tick in system suspend clocksource/drivers/arm_arch_timer: Don't assume clock runs in suspend posix-timers: Make them configurable posix_cpu_timers: Move the add_device_randomness() call to a proper place timer: Move sys_alarm from timer.c to itimer.c ptp_clock: Allow for it to be optional Kconfig: Regenerate *.c_shipped files after previous changes ...
This commit is contained in:
commit
9465d9cc31
@ -38,6 +38,11 @@ to deliver its interrupts via SPIs.
|
||||
architecturally-defined reset values. Only supported for 32-bit
|
||||
systems which follow the ARMv7 architected reset values.
|
||||
|
||||
- arm,no-tick-in-suspend : The main counter does not tick when the system is in
|
||||
low-power system suspend on some SoCs. This behavior does not match the
|
||||
Architecture Reference Manual's specification that the system counter "must
|
||||
be implemented in an always-on power domain."
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -113,6 +113,34 @@ applicable everywhere (see syntax).
|
||||
That will limit the usefulness but on the other hand avoid
|
||||
the illegal configurations all over.
|
||||
|
||||
- weak reverse dependencies: "imply" <symbol> ["if" <expr>]
|
||||
This is similar to "select" as it enforces a lower limit on another
|
||||
symbol except that the "implied" symbol's value may still be set to n
|
||||
from a direct dependency or with a visible prompt.
|
||||
|
||||
Given the following example:
|
||||
|
||||
config FOO
|
||||
tristate
|
||||
imply BAZ
|
||||
|
||||
config BAZ
|
||||
tristate
|
||||
depends on BAR
|
||||
|
||||
The following values are possible:
|
||||
|
||||
FOO BAR BAZ's default choice for BAZ
|
||||
--- --- ------------- --------------
|
||||
n y n N/m/y
|
||||
m y m M/y/n
|
||||
y y y Y/n
|
||||
y n * N
|
||||
|
||||
This is useful e.g. with multiple drivers that want to indicate their
|
||||
ability to hook into a secondary subsystem while allowing the user to
|
||||
configure that subsystem out without also having to unset these drivers.
|
||||
|
||||
- limiting menu display: "visible if" <expr>
|
||||
This attribute is only applicable to menu blocks, if the condition is
|
||||
false, the menu block is not displayed to the user (the symbols
|
||||
@ -481,6 +509,7 @@ historical issues resolved through these different solutions.
|
||||
b) Match dependency semantics:
|
||||
b1) Swap all "select FOO" to "depends on FOO" or,
|
||||
b2) Swap all "depends on FOO" to "select FOO"
|
||||
c) Consider the use of "imply" instead of "select"
|
||||
|
||||
The resolution to a) can be tested with the sample Kconfig file
|
||||
Documentation/kbuild/Kconfig.recursion-issue-01 through the removal
|
||||
|
@ -362,6 +362,26 @@ of ftrace. Here is a list of some of the key files:
|
||||
to correlate events across hypervisor/guest if
|
||||
tb_offset is known.
|
||||
|
||||
mono: This uses the fast monotonic clock (CLOCK_MONOTONIC)
|
||||
which is monotonic and is subject to NTP rate adjustments.
|
||||
|
||||
mono_raw:
|
||||
This is the raw monotonic clock (CLOCK_MONOTONIC_RAW)
|
||||
which is montonic but is not subject to any rate adjustments
|
||||
and ticks at the same rate as the hardware clocksource.
|
||||
|
||||
boot: This is the boot clock (CLOCK_BOOTTIME) and is based on the
|
||||
fast monotonic clock, but also accounts for time spent in
|
||||
suspend. Since the clock access is designed for use in
|
||||
tracing in the suspend path, some side effects are possible
|
||||
if clock is accessed after the suspend time is accounted before
|
||||
the fast mono clock is updated. In this case, the clock update
|
||||
appears to happen slightly sooner than it normally would have.
|
||||
Also on 32-bit systems, it's possible that the 64-bit boot offset
|
||||
sees a partial update. These effects are rare and post
|
||||
processing should be able to handle them. See comments in the
|
||||
ktime_get_boot_fast_ns() function for more information.
|
||||
|
||||
To set a clock, simply echo the clock name into this file.
|
||||
|
||||
echo global > trace_clock
|
||||
|
@ -1029,11 +1029,16 @@ SYSCALL_DEFINE2(osf_settimeofday, struct timeval32 __user *, tv,
|
||||
return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
|
||||
}
|
||||
|
||||
asmlinkage long sys_ni_posix_timers(void);
|
||||
|
||||
SYSCALL_DEFINE2(osf_getitimer, int, which, struct itimerval32 __user *, it)
|
||||
{
|
||||
struct itimerval kit;
|
||||
int error;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_POSIX_TIMERS))
|
||||
return sys_ni_posix_timers();
|
||||
|
||||
error = do_getitimer(which, &kit);
|
||||
if (!error && put_it32(it, &kit))
|
||||
error = -EFAULT;
|
||||
@ -1047,6 +1052,9 @@ SYSCALL_DEFINE3(osf_setitimer, int, which, struct itimerval32 __user *, in,
|
||||
struct itimerval kin, kout;
|
||||
int error;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_POSIX_TIMERS))
|
||||
return sys_ni_posix_timers();
|
||||
|
||||
if (in) {
|
||||
if (get_it32(&kin, in))
|
||||
return -EFAULT;
|
||||
|
@ -174,6 +174,7 @@
|
||||
<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW 0>,
|
||||
<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW 0>,
|
||||
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW 0>;
|
||||
arm,no-tick-in-suspend;
|
||||
};
|
||||
|
||||
xin24m: xin24m {
|
||||
|
@ -64,6 +64,15 @@ void mach_get_cmos_time(struct timespec *now)
|
||||
unsigned int status, year, mon, day, hour, min, sec, century = 0;
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* If pm_trace abused the RTC as storage, set the timespec to 0,
|
||||
* which tells the caller that this RTC value is unusable.
|
||||
*/
|
||||
if (!pm_trace_rtc_valid()) {
|
||||
now->tv_sec = now->tv_nsec = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&rtc_lock, flags);
|
||||
|
||||
/*
|
||||
|
@ -107,7 +107,7 @@ obj-$(CONFIG_INPUT) += input/
|
||||
obj-$(CONFIG_RTC_LIB) += rtc/
|
||||
obj-y += i2c/ media/
|
||||
obj-$(CONFIG_PPS) += pps/
|
||||
obj-$(CONFIG_PTP_1588_CLOCK) += ptp/
|
||||
obj-y += ptp/
|
||||
obj-$(CONFIG_W1) += w1/
|
||||
obj-y += power/
|
||||
obj-$(CONFIG_HWMON) += hwmon/
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <linux/pm-trace.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#include <linux/mc146818rtc.h>
|
||||
|
||||
@ -74,6 +75,9 @@
|
||||
|
||||
#define DEVSEED (7919)
|
||||
|
||||
bool pm_trace_rtc_abused __read_mostly;
|
||||
EXPORT_SYMBOL_GPL(pm_trace_rtc_abused);
|
||||
|
||||
static unsigned int dev_hash_value;
|
||||
|
||||
static int set_magic_time(unsigned int user, unsigned int file, unsigned int device)
|
||||
@ -104,6 +108,7 @@ static int set_magic_time(unsigned int user, unsigned int file, unsigned int dev
|
||||
time.tm_min = (n % 20) * 3;
|
||||
n /= 20;
|
||||
mc146818_set_time(&time);
|
||||
pm_trace_rtc_abused = true;
|
||||
return n ? -1 : 0;
|
||||
}
|
||||
|
||||
@ -239,9 +244,31 @@ int show_trace_dev_match(char *buf, size_t size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
pm_trace_notify(struct notifier_block *nb, unsigned long mode, void *_unused)
|
||||
{
|
||||
switch (mode) {
|
||||
case PM_POST_HIBERNATION:
|
||||
case PM_POST_SUSPEND:
|
||||
if (pm_trace_rtc_abused) {
|
||||
pm_trace_rtc_abused = false;
|
||||
pr_warn("Possible incorrect RTC due to pm_trace, please use 'ntpdate' or 'rdate' to reset it.\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct notifier_block pm_trace_nb = {
|
||||
.notifier_call = pm_trace_notify,
|
||||
};
|
||||
|
||||
static int early_resume_init(void)
|
||||
{
|
||||
hash_value_early_read = read_magic_time();
|
||||
register_pm_notifier(&pm_trace_nb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -542,6 +542,7 @@ config HANGCHECK_TIMER
|
||||
config MMTIMER
|
||||
tristate "MMTIMER Memory mapped RTC for SGI Altix"
|
||||
depends on IA64_GENERIC || IA64_SGI_SN2
|
||||
depends on POSIX_TIMERS
|
||||
default y
|
||||
help
|
||||
The mmtimer device allows direct userspace access to the
|
||||
|
@ -81,6 +81,7 @@ static struct clock_event_device __percpu *arch_timer_evt;
|
||||
static enum ppi_nr arch_timer_uses_ppi = VIRT_PPI;
|
||||
static bool arch_timer_c3stop;
|
||||
static bool arch_timer_mem_use_virtual;
|
||||
static bool arch_counter_suspend_stop;
|
||||
|
||||
static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM);
|
||||
|
||||
@ -576,7 +577,7 @@ static struct clocksource clocksource_counter = {
|
||||
.rating = 400,
|
||||
.read = arch_counter_read,
|
||||
.mask = CLOCKSOURCE_MASK(56),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP,
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
static struct cyclecounter cyclecounter = {
|
||||
@ -616,6 +617,8 @@ static void __init arch_counter_register(unsigned type)
|
||||
arch_timer_read_counter = arch_counter_get_cntvct_mem;
|
||||
}
|
||||
|
||||
if (!arch_counter_suspend_stop)
|
||||
clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
|
||||
start_count = arch_timer_read_counter();
|
||||
clocksource_register_hz(&clocksource_counter, arch_timer_rate);
|
||||
cyclecounter.mult = clocksource_counter.mult;
|
||||
@ -907,6 +910,10 @@ static int __init arch_timer_of_init(struct device_node *np)
|
||||
of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
|
||||
arch_timer_uses_ppi = PHYS_SECURE_PPI;
|
||||
|
||||
/* On some systems, the counter stops ticking when in suspend. */
|
||||
arch_counter_suspend_stop = of_property_read_bool(np,
|
||||
"arm,no-tick-in-suspend");
|
||||
|
||||
return arch_timer_init();
|
||||
}
|
||||
CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init);
|
||||
@ -964,8 +971,9 @@ static int __init arch_timer_mem_init(struct device_node *np)
|
||||
}
|
||||
|
||||
ret= -ENXIO;
|
||||
base = arch_counter_base = of_iomap(best_frame, 0);
|
||||
if (!base) {
|
||||
base = arch_counter_base = of_io_request_and_map(best_frame, 0,
|
||||
"arch_mem_timer");
|
||||
if (IS_ERR(base)) {
|
||||
pr_err("arch_timer: Can't map frame's registers\n");
|
||||
goto out;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ static int __init bcm2835_timer_init(struct device_node *node)
|
||||
ret = of_property_read_u32(node, "clock-frequency", &freq);
|
||||
if (ret) {
|
||||
pr_err("Can't read clock-frequency");
|
||||
return ret;
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
system_clock = base + REG_COUNTER_LO;
|
||||
@ -108,13 +108,15 @@ static int __init bcm2835_timer_init(struct device_node *node)
|
||||
irq = irq_of_parse_and_map(node, DEFAULT_TIMER);
|
||||
if (irq <= 0) {
|
||||
pr_err("Can't parse IRQ");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
timer = kzalloc(sizeof(*timer), GFP_KERNEL);
|
||||
if (!timer) {
|
||||
pr_err("Can't allocate timer struct\n");
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
timer->control = base + REG_CONTROL;
|
||||
@ -133,7 +135,7 @@ static int __init bcm2835_timer_init(struct device_node *node)
|
||||
ret = setup_irq(irq, &timer->act);
|
||||
if (ret) {
|
||||
pr_err("Can't set up timer IRQ\n");
|
||||
return ret;
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
clockevents_config_and_register(&timer->evt, freq, 0xf, 0xffffffff);
|
||||
@ -141,6 +143,10 @@ static int __init bcm2835_timer_init(struct device_node *node)
|
||||
pr_info("bcm2835: system timer (irq = %d)\n", irq);
|
||||
|
||||
return 0;
|
||||
|
||||
err_iounmap:
|
||||
iounmap(base);
|
||||
return ret;
|
||||
}
|
||||
CLOCKSOURCE_OF_DECLARE(bcm2835, "brcm,bcm2835-system-timer",
|
||||
bcm2835_timer_init);
|
||||
|
@ -58,7 +58,7 @@ config BFIN_RX_DESC_NUM
|
||||
config BFIN_MAC_USE_HWSTAMP
|
||||
bool "Use IEEE 1588 hwstamp"
|
||||
depends on BFIN_MAC && BF518
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
default y
|
||||
---help---
|
||||
To support the IEEE 1588 Precision Time Protocol (PTP), select y here
|
||||
|
@ -177,9 +177,9 @@ config AMD_XGBE
|
||||
depends on X86 || ARM64 || COMPILE_TEST
|
||||
select BITREVERSE
|
||||
select CRC32
|
||||
select PTP_1588_CLOCK
|
||||
select PHYLIB
|
||||
select AMD_XGBE_HAVE_ECC if X86
|
||||
imply PTP_1588_CLOCK
|
||||
---help---
|
||||
This driver supports the AMD 10GbE Ethernet device found on an
|
||||
AMD SoC.
|
||||
|
@ -422,6 +422,7 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata)
|
||||
goto err_wq;
|
||||
}
|
||||
|
||||
if (IS_REACHABLE(CONFIG_PTP_1588_CLOCK))
|
||||
xgbe_ptp_register(pdata);
|
||||
|
||||
xgbe_debugfs_init(pdata);
|
||||
@ -448,6 +449,7 @@ void xgbe_deconfig_netdev(struct xgbe_prv_data *pdata)
|
||||
|
||||
xgbe_debugfs_exit(pdata);
|
||||
|
||||
if (IS_REACHABLE(CONFIG_PTP_1588_CLOCK))
|
||||
xgbe_ptp_unregister(pdata);
|
||||
|
||||
pdata->phy_if.phy_exit(pdata);
|
||||
|
@ -110,7 +110,7 @@ config TIGON3
|
||||
depends on PCI
|
||||
select PHYLIB
|
||||
select HWMON
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
---help---
|
||||
This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
|
||||
|
||||
@ -120,7 +120,7 @@ config TIGON3
|
||||
config BNX2X
|
||||
tristate "Broadcom NetXtremeII 10Gb support"
|
||||
depends on PCI
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
select FW_LOADER
|
||||
select ZLIB_INFLATE
|
||||
select LIBCRC32C
|
||||
|
@ -53,7 +53,7 @@ config THUNDER_NIC_RGX
|
||||
config LIQUIDIO
|
||||
tristate "Cavium LiquidIO support"
|
||||
depends on 64BIT
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
select FW_LOADER
|
||||
select LIBCRC32C
|
||||
---help---
|
||||
|
@ -25,7 +25,7 @@ config FEC
|
||||
ARCH_MXC || SOC_IMX28)
|
||||
default ARCH_MXC || SOC_IMX28 if ARM
|
||||
select PHYLIB
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
---help---
|
||||
Say Y here if you want to use the built-in 10/100 Fast ethernet
|
||||
controller on some Motorola ColdFire and Freescale i.MX processors.
|
||||
|
@ -58,7 +58,7 @@ config E1000E
|
||||
tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support"
|
||||
depends on PCI && (!SPARC32 || BROKEN)
|
||||
select CRC32
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
---help---
|
||||
This driver supports the PCI-Express Intel(R) PRO/1000 gigabit
|
||||
ethernet family of adapters. For PCI or PCI-X e1000 adapters,
|
||||
@ -83,7 +83,7 @@ config E1000E_HWTS
|
||||
config IGB
|
||||
tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support"
|
||||
depends on PCI
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
select I2C
|
||||
select I2C_ALGOBIT
|
||||
---help---
|
||||
@ -156,7 +156,7 @@ config IXGBE
|
||||
tristate "Intel(R) 10GbE PCI Express adapters support"
|
||||
depends on PCI
|
||||
select MDIO
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
---help---
|
||||
This driver supports Intel(R) 10GbE PCI Express family of
|
||||
adapters. For more information on how to identify your adapter, go
|
||||
@ -213,7 +213,7 @@ config IXGBEVF
|
||||
|
||||
config I40E
|
||||
tristate "Intel(R) Ethernet Controller XL710 Family support"
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
depends on PCI
|
||||
---help---
|
||||
This driver supports Intel(R) Ethernet Controller XL710 Family of
|
||||
@ -264,7 +264,7 @@ config FM10K
|
||||
tristate "Intel(R) FM10000 Ethernet Switch Host Interface Support"
|
||||
default n
|
||||
depends on PCI_MSI
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
---help---
|
||||
This driver supports Intel(R) FM10000 Ethernet Switch Host
|
||||
Interface. For more information on how to identify your adapter,
|
||||
|
@ -7,7 +7,7 @@ config MLX4_EN
|
||||
depends on MAY_USE_DEVLINK
|
||||
depends on PCI
|
||||
select MLX4_CORE
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
---help---
|
||||
This driver supports Mellanox Technologies ConnectX Ethernet
|
||||
devices.
|
||||
|
@ -14,7 +14,7 @@ config MLX5_CORE
|
||||
config MLX5_CORE_EN
|
||||
bool "Mellanox Technologies ConnectX-4 Ethernet support"
|
||||
depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
default n
|
||||
---help---
|
||||
Ethernet support in Mellanox Technologies ConnectX-4 NIC.
|
||||
|
@ -37,7 +37,7 @@ config RAVB
|
||||
select MII
|
||||
select MDIO_BITBANG
|
||||
select PHYLIB
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
help
|
||||
Renesas Ethernet AVB device driver.
|
||||
This driver supports the following SoCs:
|
||||
|
@ -21,7 +21,7 @@ config SXGBE_ETH
|
||||
depends on HAS_IOMEM && HAS_DMA
|
||||
select PHYLIB
|
||||
select CRC32
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
---help---
|
||||
This is the driver for the SXGBE 10G Ethernet IP block found on
|
||||
Samsung platforms.
|
||||
|
@ -5,7 +5,7 @@ config SFC
|
||||
select CRC32
|
||||
select I2C
|
||||
select I2C_ALGOBIT
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
---help---
|
||||
This driver supports 10/40-gigabit Ethernet cards based on
|
||||
the Solarflare SFC9000-family and SFC9100-family controllers.
|
||||
|
@ -4,7 +4,7 @@ config STMMAC_ETH
|
||||
select MII
|
||||
select PHYLIB
|
||||
select CRC32
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
select RESET_CONTROLLER
|
||||
---help---
|
||||
This is the driver for the Ethernet IPs are built around a
|
||||
|
@ -76,7 +76,7 @@ config TI_CPSW
|
||||
config TI_CPTS
|
||||
tristate "TI Common Platform Time Sync (CPTS) Support"
|
||||
depends on TI_CPSW || TI_KEYSTONE_NETCP
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
---help---
|
||||
This driver supports the Common Platform Time Sync unit of
|
||||
the CPSW Ethernet Switch and Keystone 2 1g/10g Switch Subsystem.
|
||||
|
@ -9,7 +9,7 @@ config TILE_NET
|
||||
select CRC32
|
||||
select TILE_GXIO_MPIPE if TILEGX
|
||||
select HIGH_RES_TIMERS if TILEGX
|
||||
select PTP_1588_CLOCK if TILEGX
|
||||
imply PTP_1588_CLOCK if TILEGX
|
||||
---help---
|
||||
This is a standard Linux network device driver for the
|
||||
on-chip Tilera Gigabit Ethernet and XAUI interfaces.
|
||||
|
@ -6,7 +6,7 @@ menu "PTP clock support"
|
||||
|
||||
config PTP_1588_CLOCK
|
||||
tristate "PTP clock support"
|
||||
depends on NET
|
||||
depends on NET && POSIX_TIMERS
|
||||
select PPS
|
||||
select NET_PTP_CLASSIFY
|
||||
help
|
||||
@ -28,7 +28,7 @@ config PTP_1588_CLOCK
|
||||
config PTP_1588_CLOCK_GIANFAR
|
||||
tristate "Freescale eTSEC as PTP clock"
|
||||
depends on GIANFAR
|
||||
select PTP_1588_CLOCK
|
||||
depends on PTP_1588_CLOCK
|
||||
default y
|
||||
help
|
||||
This driver adds support for using the eTSEC as a PTP
|
||||
@ -42,7 +42,7 @@ config PTP_1588_CLOCK_GIANFAR
|
||||
config PTP_1588_CLOCK_IXP46X
|
||||
tristate "Intel IXP46x as PTP clock"
|
||||
depends on IXP4XX_ETH
|
||||
select PTP_1588_CLOCK
|
||||
depends on PTP_1588_CLOCK
|
||||
default y
|
||||
help
|
||||
This driver adds support for using the IXP46X as a PTP
|
||||
@ -60,7 +60,7 @@ config DP83640_PHY
|
||||
tristate "Driver for the National Semiconductor DP83640 PHYTER"
|
||||
depends on NETWORK_PHY_TIMESTAMPING
|
||||
depends on PHYLIB
|
||||
select PTP_1588_CLOCK
|
||||
depends on PTP_1588_CLOCK
|
||||
---help---
|
||||
Supports the DP83640 PHYTER with IEEE 1588 features.
|
||||
|
||||
@ -76,7 +76,7 @@ config PTP_1588_CLOCK_PCH
|
||||
tristate "Intel PCH EG20T as PTP clock"
|
||||
depends on X86_32 || COMPILE_TEST
|
||||
depends on HAS_IOMEM && NET
|
||||
select PTP_1588_CLOCK
|
||||
imply PTP_1588_CLOCK
|
||||
help
|
||||
This driver adds support for using the PCH EG20T as a PTP
|
||||
clock. The hardware supports time stamping of PTP packets
|
||||
|
@ -191,6 +191,13 @@ static inline void cmos_write_bank2(unsigned char val, unsigned char addr)
|
||||
|
||||
static int cmos_read_time(struct device *dev, struct rtc_time *t)
|
||||
{
|
||||
/*
|
||||
* If pm_trace abused the RTC for storage, set the timespec to 0,
|
||||
* which tells the caller that this RTC value is unusable.
|
||||
*/
|
||||
if (!pm_trace_rtc_valid())
|
||||
return -EIO;
|
||||
|
||||
/* REVISIT: if the clock has a "century" register, use
|
||||
* that instead of the heuristic in mc146818_get_time().
|
||||
* That'll make Y3K compatility (year > 2070) easy!
|
||||
|
@ -1169,8 +1169,10 @@ no_thread_group:
|
||||
/* we have changed execution domain */
|
||||
tsk->exit_signal = SIGCHLD;
|
||||
|
||||
#ifdef CONFIG_POSIX_TIMERS
|
||||
exit_itimers(sig);
|
||||
flush_itimer_signals();
|
||||
#endif
|
||||
|
||||
if (atomic_read(&oldsighand->count) != 1) {
|
||||
struct sighand_struct *newsighand;
|
||||
|
@ -10,7 +10,12 @@ enum alarmtimer_type {
|
||||
ALARM_REALTIME,
|
||||
ALARM_BOOTTIME,
|
||||
|
||||
/* Supported types end here */
|
||||
ALARM_NUMTYPE,
|
||||
|
||||
/* Used for tracing information. No usable types. */
|
||||
ALARM_REALTIME_FREEZER,
|
||||
ALARM_BOOTTIME_FREEZER,
|
||||
};
|
||||
|
||||
enum alarmtimer_restart {
|
||||
|
@ -169,7 +169,10 @@ static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
|
||||
* @mult: cycle to nanosecond multiplier
|
||||
* @shift: cycle to nanosecond divisor (power of two)
|
||||
*
|
||||
* Converts cycles to nanoseconds, using the given mult and shift.
|
||||
* Converts clocksource cycles to nanoseconds, using the given @mult and @shift.
|
||||
* The code is optimized for performance and is not intended to work
|
||||
* with absolute clocksource cycles (as those will easily overflow),
|
||||
* but is only intended to be used with relative (delta) clocksource cycles.
|
||||
*
|
||||
* XXX - This could use some mult_lxl_ll() asm optimization
|
||||
*/
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <asm/mc146818rtc.h> /* register access macros */
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pm-trace.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/spinlock.h> /* spinlock_t */
|
||||
|
@ -1,11 +1,17 @@
|
||||
#ifndef PM_TRACE_H
|
||||
#define PM_TRACE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#ifdef CONFIG_PM_TRACE
|
||||
#include <asm/pm-trace.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
extern int pm_trace_enabled;
|
||||
extern bool pm_trace_rtc_abused;
|
||||
|
||||
static inline bool pm_trace_rtc_valid(void)
|
||||
{
|
||||
return !pm_trace_rtc_abused;
|
||||
}
|
||||
|
||||
static inline int pm_trace_is_enabled(void)
|
||||
{
|
||||
@ -24,6 +30,7 @@ extern int show_trace_dev_match(char *buf, size_t size);
|
||||
|
||||
#else
|
||||
|
||||
static inline bool pm_trace_rtc_valid(void) { return true; }
|
||||
static inline int pm_trace_is_enabled(void) { return 0; }
|
||||
|
||||
#define TRACE_DEVICE(dev) do { } while (0)
|
||||
|
@ -130,30 +130,6 @@ struct ptp_clock_info {
|
||||
|
||||
struct ptp_clock;
|
||||
|
||||
/**
|
||||
* ptp_clock_register() - register a PTP hardware clock driver
|
||||
*
|
||||
* @info: Structure describing the new clock.
|
||||
* @parent: Pointer to the parent device of the new clock.
|
||||
*
|
||||
* Returns a valid pointer on success or PTR_ERR on failure. If PHC
|
||||
* support is missing at the configuration level, this function
|
||||
* returns NULL, and drivers are expected to gracefully handle that
|
||||
* case separately.
|
||||
*/
|
||||
|
||||
extern struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
|
||||
struct device *parent);
|
||||
|
||||
/**
|
||||
* ptp_clock_unregister() - unregister a PTP hardware clock driver
|
||||
*
|
||||
* @ptp: The clock to remove from service.
|
||||
*/
|
||||
|
||||
extern int ptp_clock_unregister(struct ptp_clock *ptp);
|
||||
|
||||
|
||||
enum ptp_clock_events {
|
||||
PTP_CLOCK_ALARM,
|
||||
PTP_CLOCK_EXTTS,
|
||||
@ -179,6 +155,31 @@ struct ptp_clock_event {
|
||||
};
|
||||
};
|
||||
|
||||
#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
|
||||
|
||||
/**
|
||||
* ptp_clock_register() - register a PTP hardware clock driver
|
||||
*
|
||||
* @info: Structure describing the new clock.
|
||||
* @parent: Pointer to the parent device of the new clock.
|
||||
*
|
||||
* Returns a valid pointer on success or PTR_ERR on failure. If PHC
|
||||
* support is missing at the configuration level, this function
|
||||
* returns NULL, and drivers are expected to gracefully handle that
|
||||
* case separately.
|
||||
*/
|
||||
|
||||
extern struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
|
||||
struct device *parent);
|
||||
|
||||
/**
|
||||
* ptp_clock_unregister() - unregister a PTP hardware clock driver
|
||||
*
|
||||
* @ptp: The clock to remove from service.
|
||||
*/
|
||||
|
||||
extern int ptp_clock_unregister(struct ptp_clock *ptp);
|
||||
|
||||
/**
|
||||
* ptp_clock_event() - notify the PTP layer about an event
|
||||
*
|
||||
@ -210,4 +211,20 @@ extern int ptp_clock_index(struct ptp_clock *ptp);
|
||||
int ptp_find_pin(struct ptp_clock *ptp,
|
||||
enum ptp_pin_function func, unsigned int chan);
|
||||
|
||||
#else
|
||||
static inline struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
|
||||
struct device *parent)
|
||||
{ return NULL; }
|
||||
static inline int ptp_clock_unregister(struct ptp_clock *ptp)
|
||||
{ return 0; }
|
||||
static inline void ptp_clock_event(struct ptp_clock *ptp,
|
||||
struct ptp_clock_event *event)
|
||||
{ }
|
||||
static inline int ptp_clock_index(struct ptp_clock *ptp)
|
||||
{ return -1; }
|
||||
static inline int ptp_find_pin(struct ptp_clock *ptp,
|
||||
enum ptp_pin_function func, unsigned int chan)
|
||||
{ return -1; }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -172,8 +172,6 @@ extern int do_setitimer(int which, struct itimerval *value,
|
||||
struct itimerval *ovalue);
|
||||
extern int do_getitimer(int which, struct itimerval *value);
|
||||
|
||||
extern unsigned int alarm_setitimer(unsigned int seconds);
|
||||
|
||||
extern long do_utimes(int dfd, const char __user *filename, struct timespec *times, int flags);
|
||||
|
||||
struct tms;
|
||||
|
@ -249,6 +249,7 @@ static inline u64 ktime_get_raw_ns(void)
|
||||
|
||||
extern u64 ktime_get_mono_fast_ns(void);
|
||||
extern u64 ktime_get_raw_fast_ns(void);
|
||||
extern u64 ktime_get_boot_fast_ns(void);
|
||||
|
||||
/*
|
||||
* Timespec interfaces utilizing the ktime based ones
|
||||
|
96
include/trace/events/alarmtimer.h
Normal file
96
include/trace/events/alarmtimer.h
Normal file
@ -0,0 +1,96 @@
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM alarmtimer
|
||||
|
||||
#if !defined(_TRACE_ALARMTIMER_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define _TRACE_ALARMTIMER_H
|
||||
|
||||
#include <linux/alarmtimer.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
TRACE_DEFINE_ENUM(ALARM_REALTIME);
|
||||
TRACE_DEFINE_ENUM(ALARM_BOOTTIME);
|
||||
TRACE_DEFINE_ENUM(ALARM_REALTIME_FREEZER);
|
||||
TRACE_DEFINE_ENUM(ALARM_BOOTTIME_FREEZER);
|
||||
|
||||
#define show_alarm_type(type) __print_flags(type, " | ", \
|
||||
{ 1 << ALARM_REALTIME, "REALTIME" }, \
|
||||
{ 1 << ALARM_BOOTTIME, "BOOTTIME" }, \
|
||||
{ 1 << ALARM_REALTIME_FREEZER, "REALTIME Freezer" }, \
|
||||
{ 1 << ALARM_BOOTTIME_FREEZER, "BOOTTIME Freezer" })
|
||||
|
||||
TRACE_EVENT(alarmtimer_suspend,
|
||||
|
||||
TP_PROTO(ktime_t expires, int flag),
|
||||
|
||||
TP_ARGS(expires, flag),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(s64, expires)
|
||||
__field(unsigned char, alarm_type)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->expires = expires.tv64;
|
||||
__entry->alarm_type = flag;
|
||||
),
|
||||
|
||||
TP_printk("alarmtimer type:%s expires:%llu",
|
||||
show_alarm_type((1 << __entry->alarm_type)),
|
||||
__entry->expires
|
||||
)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(alarm_class,
|
||||
|
||||
TP_PROTO(struct alarm *alarm, ktime_t now),
|
||||
|
||||
TP_ARGS(alarm, now),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(void *, alarm)
|
||||
__field(unsigned char, alarm_type)
|
||||
__field(s64, expires)
|
||||
__field(s64, now)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->alarm = alarm;
|
||||
__entry->alarm_type = alarm->type;
|
||||
__entry->expires = alarm->node.expires.tv64;
|
||||
__entry->now = now.tv64;
|
||||
),
|
||||
|
||||
TP_printk("alarmtimer:%p type:%s expires:%llu now:%llu",
|
||||
__entry->alarm,
|
||||
show_alarm_type((1 << __entry->alarm_type)),
|
||||
__entry->expires,
|
||||
__entry->now
|
||||
)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(alarm_class, alarmtimer_fired,
|
||||
|
||||
TP_PROTO(struct alarm *alarm, ktime_t now),
|
||||
|
||||
TP_ARGS(alarm, now)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(alarm_class, alarmtimer_start,
|
||||
|
||||
TP_PROTO(struct alarm *alarm, ktime_t now),
|
||||
|
||||
TP_ARGS(alarm, now)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(alarm_class, alarmtimer_cancel,
|
||||
|
||||
TP_PROTO(struct alarm *alarm, ktime_t now),
|
||||
|
||||
TP_ARGS(alarm, now)
|
||||
);
|
||||
|
||||
#endif /* _TRACE_ALARMTIMER_H */
|
||||
|
||||
/* This part must be outside protection */
|
||||
#include <trace/define_trace.h>
|
17
init/Kconfig
17
init/Kconfig
@ -1457,6 +1457,23 @@ config SYSCTL_SYSCALL
|
||||
|
||||
If unsure say N here.
|
||||
|
||||
config POSIX_TIMERS
|
||||
bool "Posix Clocks & timers" if EXPERT
|
||||
default y
|
||||
help
|
||||
This includes native support for POSIX timers to the kernel.
|
||||
Some embedded systems have no use for them and therefore they
|
||||
can be configured out to reduce the size of the kernel image.
|
||||
|
||||
When this option is disabled, the following syscalls won't be
|
||||
available: timer_create, timer_gettime: timer_getoverrun,
|
||||
timer_settime, timer_delete, clock_adjtime, getitimer,
|
||||
setitimer, alarm. Furthermore, the clock_settime, clock_gettime,
|
||||
clock_getres and clock_nanosleep syscalls will be limited to
|
||||
CLOCK_REALTIME, CLOCK_MONOTONIC and CLOCK_BOOTTIME only.
|
||||
|
||||
If unsure say y.
|
||||
|
||||
config KALLSYMS
|
||||
bool "Load all symbols for debugging/ksymoops" if EXPERT
|
||||
default y
|
||||
|
@ -307,12 +307,17 @@ static inline long put_compat_itimerval(struct compat_itimerval __user *o,
|
||||
__put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
|
||||
}
|
||||
|
||||
asmlinkage long sys_ni_posix_timers(void);
|
||||
|
||||
COMPAT_SYSCALL_DEFINE2(getitimer, int, which,
|
||||
struct compat_itimerval __user *, it)
|
||||
{
|
||||
struct itimerval kit;
|
||||
int error;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_POSIX_TIMERS))
|
||||
return sys_ni_posix_timers();
|
||||
|
||||
error = do_getitimer(which, &kit);
|
||||
if (!error && put_compat_itimerval(it, &kit))
|
||||
error = -EFAULT;
|
||||
@ -326,6 +331,9 @@ COMPAT_SYSCALL_DEFINE3(setitimer, int, which,
|
||||
struct itimerval kin, kout;
|
||||
int error;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_POSIX_TIMERS))
|
||||
return sys_ni_posix_timers();
|
||||
|
||||
if (in) {
|
||||
if (get_compat_itimerval(&kin, in))
|
||||
return -EFAULT;
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include <linux/writeback.h>
|
||||
#include <linux/shm.h>
|
||||
#include <linux/kcov.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/unistd.h>
|
||||
@ -91,11 +92,10 @@ static void __exit_signal(struct task_struct *tsk)
|
||||
lockdep_tasklist_lock_is_held());
|
||||
spin_lock(&sighand->siglock);
|
||||
|
||||
#ifdef CONFIG_POSIX_TIMERS
|
||||
posix_cpu_timers_exit(tsk);
|
||||
if (group_dead) {
|
||||
posix_cpu_timers_exit_group(tsk);
|
||||
tty = sig->tty;
|
||||
sig->tty = NULL;
|
||||
} else {
|
||||
/*
|
||||
* This can only happen if the caller is de_thread().
|
||||
@ -104,7 +104,13 @@ static void __exit_signal(struct task_struct *tsk)
|
||||
*/
|
||||
if (unlikely(has_group_leader_pid(tsk)))
|
||||
posix_cpu_timers_exit_group(tsk);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (group_dead) {
|
||||
tty = sig->tty;
|
||||
sig->tty = NULL;
|
||||
} else {
|
||||
/*
|
||||
* If there is any task waiting for the group exit
|
||||
* then notify it:
|
||||
@ -116,6 +122,9 @@ static void __exit_signal(struct task_struct *tsk)
|
||||
sig->curr_target = next_thread(tsk);
|
||||
}
|
||||
|
||||
add_device_randomness((const void*) &tsk->se.sum_exec_runtime,
|
||||
sizeof(unsigned long long));
|
||||
|
||||
/*
|
||||
* Accumulate here the counters for all threads as they die. We could
|
||||
* skip the group leader because it is the last user of signal_struct,
|
||||
@ -799,8 +808,10 @@ void __noreturn do_exit(long code)
|
||||
acct_update_integrals(tsk);
|
||||
group_dead = atomic_dec_and_test(&tsk->signal->live);
|
||||
if (group_dead) {
|
||||
#ifdef CONFIG_POSIX_TIMERS
|
||||
hrtimer_cancel(&tsk->signal->real_timer);
|
||||
exit_itimers(tsk->signal);
|
||||
#endif
|
||||
if (tsk->mm)
|
||||
setmax_mm_hiwater_rss(&tsk->signal->maxrss, tsk->mm);
|
||||
}
|
||||
|
@ -1347,8 +1347,10 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
|
||||
seqlock_init(&sig->stats_lock);
|
||||
prev_cputime_init(&sig->prev_cputime);
|
||||
|
||||
#ifdef CONFIG_POSIX_TIMERS
|
||||
hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
sig->real_timer.function = it_real_fn;
|
||||
#endif
|
||||
|
||||
task_lock(current->group_leader);
|
||||
memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
|
||||
|
@ -427,6 +427,7 @@ void flush_signals(struct task_struct *t)
|
||||
spin_unlock_irqrestore(&t->sighand->siglock, flags);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_POSIX_TIMERS
|
||||
static void __flush_itimer_signals(struct sigpending *pending)
|
||||
{
|
||||
sigset_t signal, retain;
|
||||
@ -460,6 +461,7 @@ void flush_itimer_signals(void)
|
||||
__flush_itimer_signals(&tsk->signal->shared_pending);
|
||||
spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ignore_signals(struct task_struct *t)
|
||||
{
|
||||
@ -567,6 +569,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
|
||||
if (!signr) {
|
||||
signr = __dequeue_signal(&tsk->signal->shared_pending,
|
||||
mask, info);
|
||||
#ifdef CONFIG_POSIX_TIMERS
|
||||
/*
|
||||
* itimer signal ?
|
||||
*
|
||||
@ -590,6 +593,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
|
||||
hrtimer_restart(tmr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
recalc_sigpending();
|
||||
@ -611,6 +615,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
|
||||
*/
|
||||
current->jobctl |= JOBCTL_STOP_DEQUEUED;
|
||||
}
|
||||
#ifdef CONFIG_POSIX_TIMERS
|
||||
if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) {
|
||||
/*
|
||||
* Release the siglock to ensure proper locking order
|
||||
@ -622,6 +627,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
|
||||
do_schedule_next_timer(info);
|
||||
spin_lock(&tsk->sighand->siglock);
|
||||
}
|
||||
#endif
|
||||
return signr;
|
||||
}
|
||||
|
||||
|
@ -1416,7 +1416,8 @@ int do_prlimit(struct task_struct *tsk, unsigned int resource,
|
||||
* applications, so we live with it
|
||||
*/
|
||||
if (!retval && new_rlim && resource == RLIMIT_CPU &&
|
||||
new_rlim->rlim_cur != RLIM_INFINITY)
|
||||
new_rlim->rlim_cur != RLIM_INFINITY &&
|
||||
IS_ENABLED(CONFIG_POSIX_TIMERS))
|
||||
update_rlimit_cpu(tsk, new_rlim->rlim_cur);
|
||||
out:
|
||||
read_unlock(&tasklist_lock);
|
||||
|
@ -1,6 +1,12 @@
|
||||
obj-y += time.o timer.o hrtimer.o itimer.o posix-timers.o posix-cpu-timers.o
|
||||
obj-y += time.o timer.o hrtimer.o
|
||||
obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o
|
||||
obj-y += timeconv.o timecounter.o posix-clock.o alarmtimer.o
|
||||
obj-y += timeconv.o timecounter.o alarmtimer.o
|
||||
|
||||
ifeq ($(CONFIG_POSIX_TIMERS),y)
|
||||
obj-y += posix-timers.o posix-cpu-timers.o posix-clock.o itimer.o
|
||||
else
|
||||
obj-y += posix-stubs.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_GENERIC_CLOCKEVENTS) += clockevents.o tick-common.o
|
||||
ifeq ($(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST),y)
|
||||
|
@ -26,6 +26,9 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/freezer.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/alarmtimer.h>
|
||||
|
||||
/**
|
||||
* struct alarm_base - Alarm timer bases
|
||||
* @lock: Lock for syncrhonized access to the base
|
||||
@ -40,7 +43,9 @@ static struct alarm_base {
|
||||
clockid_t base_clockid;
|
||||
} alarm_bases[ALARM_NUMTYPE];
|
||||
|
||||
/* freezer delta & lock used to handle clock_nanosleep triggered wakeups */
|
||||
/* freezer information to handle clock_nanosleep triggered wakeups */
|
||||
static enum alarmtimer_type freezer_alarmtype;
|
||||
static ktime_t freezer_expires;
|
||||
static ktime_t freezer_delta;
|
||||
static DEFINE_SPINLOCK(freezer_delta_lock);
|
||||
|
||||
@ -194,6 +199,7 @@ static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer)
|
||||
}
|
||||
spin_unlock_irqrestore(&base->lock, flags);
|
||||
|
||||
trace_alarmtimer_fired(alarm, base->gettime());
|
||||
return ret;
|
||||
|
||||
}
|
||||
@ -218,15 +224,16 @@ EXPORT_SYMBOL_GPL(alarm_expires_remaining);
|
||||
*/
|
||||
static int alarmtimer_suspend(struct device *dev)
|
||||
{
|
||||
struct rtc_time tm;
|
||||
ktime_t min, now;
|
||||
unsigned long flags;
|
||||
ktime_t min, now, expires;
|
||||
int i, ret, type;
|
||||
struct rtc_device *rtc;
|
||||
int i;
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
struct rtc_time tm;
|
||||
|
||||
spin_lock_irqsave(&freezer_delta_lock, flags);
|
||||
min = freezer_delta;
|
||||
expires = freezer_expires;
|
||||
type = freezer_alarmtype;
|
||||
freezer_delta = ktime_set(0, 0);
|
||||
spin_unlock_irqrestore(&freezer_delta_lock, flags);
|
||||
|
||||
@ -247,8 +254,11 @@ static int alarmtimer_suspend(struct device *dev)
|
||||
if (!next)
|
||||
continue;
|
||||
delta = ktime_sub(next->expires, base->gettime());
|
||||
if (!min.tv64 || (delta.tv64 < min.tv64))
|
||||
if (!min.tv64 || (delta.tv64 < min.tv64)) {
|
||||
expires = next->expires;
|
||||
min = delta;
|
||||
type = i;
|
||||
}
|
||||
}
|
||||
if (min.tv64 == 0)
|
||||
return 0;
|
||||
@ -258,6 +268,8 @@ static int alarmtimer_suspend(struct device *dev)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
trace_alarmtimer_suspend(expires, type);
|
||||
|
||||
/* Setup an rtc timer to fire that far in the future */
|
||||
rtc_timer_cancel(rtc, &rtctimer);
|
||||
rtc_read_time(rtc, &tm);
|
||||
@ -295,15 +307,32 @@ static int alarmtimer_resume(struct device *dev)
|
||||
|
||||
static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type)
|
||||
{
|
||||
ktime_t delta;
|
||||
struct alarm_base *base;
|
||||
unsigned long flags;
|
||||
struct alarm_base *base = &alarm_bases[type];
|
||||
ktime_t delta;
|
||||
|
||||
switch(type) {
|
||||
case ALARM_REALTIME:
|
||||
base = &alarm_bases[ALARM_REALTIME];
|
||||
type = ALARM_REALTIME_FREEZER;
|
||||
break;
|
||||
case ALARM_BOOTTIME:
|
||||
base = &alarm_bases[ALARM_BOOTTIME];
|
||||
type = ALARM_BOOTTIME_FREEZER;
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(1, "Invalid alarm type: %d\n", type);
|
||||
return;
|
||||
}
|
||||
|
||||
delta = ktime_sub(absexp, base->gettime());
|
||||
|
||||
spin_lock_irqsave(&freezer_delta_lock, flags);
|
||||
if (!freezer_delta.tv64 || (delta.tv64 < freezer_delta.tv64))
|
||||
if (!freezer_delta.tv64 || (delta.tv64 < freezer_delta.tv64)) {
|
||||
freezer_delta = delta;
|
||||
freezer_expires = absexp;
|
||||
freezer_alarmtype = type;
|
||||
}
|
||||
spin_unlock_irqrestore(&freezer_delta_lock, flags);
|
||||
}
|
||||
|
||||
@ -342,6 +371,8 @@ void alarm_start(struct alarm *alarm, ktime_t start)
|
||||
alarmtimer_enqueue(base, alarm);
|
||||
hrtimer_start(&alarm->timer, alarm->node.expires, HRTIMER_MODE_ABS);
|
||||
spin_unlock_irqrestore(&base->lock, flags);
|
||||
|
||||
trace_alarmtimer_start(alarm, base->gettime());
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(alarm_start);
|
||||
|
||||
@ -390,6 +421,8 @@ int alarm_try_to_cancel(struct alarm *alarm)
|
||||
if (ret >= 0)
|
||||
alarmtimer_dequeue(base, alarm);
|
||||
spin_unlock_irqrestore(&base->lock, flags);
|
||||
|
||||
trace_alarmtimer_cancel(alarm, base->gettime());
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(alarm_try_to_cancel);
|
||||
@ -846,8 +879,10 @@ static int __init alarmtimer_init(void)
|
||||
|
||||
alarmtimer_rtc_timer_init();
|
||||
|
||||
if (IS_ENABLED(CONFIG_POSIX_TIMERS)) {
|
||||
posix_timers_register_clock(CLOCK_REALTIME_ALARM, &alarm_clock);
|
||||
posix_timers_register_clock(CLOCK_BOOTTIME_ALARM, &alarm_clock);
|
||||
}
|
||||
|
||||
/* Initialize alarm bases */
|
||||
alarm_bases[ALARM_REALTIME].base_clockid = CLOCK_REALTIME;
|
||||
|
@ -1742,15 +1742,19 @@ schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta,
|
||||
* You can set the task state as follows -
|
||||
*
|
||||
* %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to
|
||||
* pass before the routine returns.
|
||||
* pass before the routine returns unless the current task is explicitly
|
||||
* woken up, (e.g. by wake_up_process()).
|
||||
*
|
||||
* %TASK_INTERRUPTIBLE - the routine may return early if a signal is
|
||||
* delivered to the current task.
|
||||
* delivered to the current task or the current task is explicitly woken
|
||||
* up.
|
||||
*
|
||||
* The current task state is guaranteed to be TASK_RUNNING when this
|
||||
* routine returns.
|
||||
*
|
||||
* Returns 0 when the timer has expired otherwise -EINTR
|
||||
* Returns 0 when the timer has expired. If the task was woken before the
|
||||
* timer expired by a signal (only possible in state TASK_INTERRUPTIBLE) or
|
||||
* by an explicit wakeup, it returns -EINTR.
|
||||
*/
|
||||
int __sched schedule_hrtimeout_range(ktime_t *expires, u64 delta,
|
||||
const enum hrtimer_mode mode)
|
||||
@ -1772,15 +1776,19 @@ EXPORT_SYMBOL_GPL(schedule_hrtimeout_range);
|
||||
* You can set the task state as follows -
|
||||
*
|
||||
* %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to
|
||||
* pass before the routine returns.
|
||||
* pass before the routine returns unless the current task is explicitly
|
||||
* woken up, (e.g. by wake_up_process()).
|
||||
*
|
||||
* %TASK_INTERRUPTIBLE - the routine may return early if a signal is
|
||||
* delivered to the current task.
|
||||
* delivered to the current task or the current task is explicitly woken
|
||||
* up.
|
||||
*
|
||||
* The current task state is guaranteed to be TASK_RUNNING when this
|
||||
* routine returns.
|
||||
*
|
||||
* Returns 0 when the timer has expired otherwise -EINTR
|
||||
* Returns 0 when the timer has expired. If the task was woken before the
|
||||
* timer expired by a signal (only possible in state TASK_INTERRUPTIBLE) or
|
||||
* by an explicit wakeup, it returns -EINTR.
|
||||
*/
|
||||
int __sched schedule_hrtimeout(ktime_t *expires,
|
||||
const enum hrtimer_mode mode)
|
||||
|
@ -238,6 +238,8 @@ again:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __ARCH_WANT_SYS_ALARM
|
||||
|
||||
/**
|
||||
* alarm_setitimer - set alarm in seconds
|
||||
*
|
||||
@ -250,7 +252,7 @@ again:
|
||||
* On 32 bit machines the seconds value is limited to (INT_MAX/2) to avoid
|
||||
* negative timeval settings which would cause immediate expiry.
|
||||
*/
|
||||
unsigned int alarm_setitimer(unsigned int seconds)
|
||||
static unsigned int alarm_setitimer(unsigned int seconds)
|
||||
{
|
||||
struct itimerval it_new, it_old;
|
||||
|
||||
@ -275,6 +277,17 @@ unsigned int alarm_setitimer(unsigned int seconds)
|
||||
return it_old.it_value.tv_sec;
|
||||
}
|
||||
|
||||
/*
|
||||
* For backwards compatibility? This can be done in libc so Alpha
|
||||
* and all newer ports shouldn't need it.
|
||||
*/
|
||||
SYSCALL_DEFINE1(alarm, unsigned int, seconds)
|
||||
{
|
||||
return alarm_setitimer(seconds);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value,
|
||||
struct itimerval __user *, ovalue)
|
||||
{
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <trace/events/timer.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/tick.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
@ -447,10 +446,7 @@ static void cleanup_timers(struct list_head *head)
|
||||
*/
|
||||
void posix_cpu_timers_exit(struct task_struct *tsk)
|
||||
{
|
||||
add_device_randomness((const void*) &tsk->se.sum_exec_runtime,
|
||||
sizeof(unsigned long long));
|
||||
cleanup_timers(tsk->cpu_timers);
|
||||
|
||||
}
|
||||
void posix_cpu_timers_exit_group(struct task_struct *tsk)
|
||||
{
|
||||
|
123
kernel/time/posix-stubs.c
Normal file
123
kernel/time/posix-stubs.c
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Dummy stubs used when CONFIG_POSIX_TIMERS=n
|
||||
*
|
||||
* Created by: Nicolas Pitre, July 2016
|
||||
* Copyright: (C) 2016 Linaro Limited
|
||||
*
|
||||
* 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/linkage.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/timekeeping.h>
|
||||
#include <linux/posix-timers.h>
|
||||
|
||||
asmlinkage long sys_ni_posix_timers(void)
|
||||
{
|
||||
pr_err_once("process %d (%s) attempted a POSIX timer syscall "
|
||||
"while CONFIG_POSIX_TIMERS is not set\n",
|
||||
current->pid, current->comm);
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
#define SYS_NI(name) SYSCALL_ALIAS(sys_##name, sys_ni_posix_timers)
|
||||
|
||||
SYS_NI(timer_create);
|
||||
SYS_NI(timer_gettime);
|
||||
SYS_NI(timer_getoverrun);
|
||||
SYS_NI(timer_settime);
|
||||
SYS_NI(timer_delete);
|
||||
SYS_NI(clock_adjtime);
|
||||
SYS_NI(getitimer);
|
||||
SYS_NI(setitimer);
|
||||
#ifdef __ARCH_WANT_SYS_ALARM
|
||||
SYS_NI(alarm);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC
|
||||
* as it is easy to remain compatible with little code. CLOCK_BOOTTIME
|
||||
* is also included for convenience as at least systemd uses it.
|
||||
*/
|
||||
|
||||
SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
|
||||
const struct timespec __user *, tp)
|
||||
{
|
||||
struct timespec new_tp;
|
||||
|
||||
if (which_clock != CLOCK_REALTIME)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&new_tp, tp, sizeof (*tp)))
|
||||
return -EFAULT;
|
||||
return do_sys_settimeofday(&new_tp, NULL);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
|
||||
struct timespec __user *,tp)
|
||||
{
|
||||
struct timespec kernel_tp;
|
||||
|
||||
switch (which_clock) {
|
||||
case CLOCK_REALTIME: ktime_get_real_ts(&kernel_tp); break;
|
||||
case CLOCK_MONOTONIC: ktime_get_ts(&kernel_tp); break;
|
||||
case CLOCK_BOOTTIME: get_monotonic_boottime(&kernel_tp); break;
|
||||
default: return -EINVAL;
|
||||
}
|
||||
if (copy_to_user(tp, &kernel_tp, sizeof (kernel_tp)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp)
|
||||
{
|
||||
struct timespec rtn_tp = {
|
||||
.tv_sec = 0,
|
||||
.tv_nsec = hrtimer_resolution,
|
||||
};
|
||||
|
||||
switch (which_clock) {
|
||||
case CLOCK_REALTIME:
|
||||
case CLOCK_MONOTONIC:
|
||||
case CLOCK_BOOTTIME:
|
||||
if (copy_to_user(tp, &rtn_tp, sizeof(rtn_tp)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
|
||||
const struct timespec __user *, rqtp,
|
||||
struct timespec __user *, rmtp)
|
||||
{
|
||||
struct timespec t;
|
||||
|
||||
switch (which_clock) {
|
||||
case CLOCK_REALTIME:
|
||||
case CLOCK_MONOTONIC:
|
||||
case CLOCK_BOOTTIME:
|
||||
if (copy_from_user(&t, rqtp, sizeof (struct timespec)))
|
||||
return -EFAULT;
|
||||
if (!timespec_valid(&t))
|
||||
return -EINVAL;
|
||||
return hrtimer_nanosleep(&t, rmtp, flags & TIMER_ABSTIME ?
|
||||
HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
|
||||
which_clock);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
long clock_nanosleep_restart(struct restart_block *restart_block)
|
||||
{
|
||||
return hrtimer_nanosleep_restart(restart_block);
|
||||
}
|
||||
#endif
|
@ -258,10 +258,9 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock)
|
||||
tk->cycle_interval = interval;
|
||||
|
||||
/* Go back from cycles -> shifted ns */
|
||||
tk->xtime_interval = (u64) interval * clock->mult;
|
||||
tk->xtime_interval = interval * clock->mult;
|
||||
tk->xtime_remainder = ntpinterval - tk->xtime_interval;
|
||||
tk->raw_interval =
|
||||
((u64) interval * clock->mult) >> clock->shift;
|
||||
tk->raw_interval = (interval * clock->mult) >> clock->shift;
|
||||
|
||||
/* if changing clocks, convert xtime_nsec shift units */
|
||||
if (old_clock) {
|
||||
@ -299,10 +298,10 @@ u32 (*arch_gettimeoffset)(void) = default_arch_gettimeoffset;
|
||||
static inline u32 arch_gettimeoffset(void) { return 0; }
|
||||
#endif
|
||||
|
||||
static inline s64 timekeeping_delta_to_ns(struct tk_read_base *tkr,
|
||||
static inline u64 timekeeping_delta_to_ns(struct tk_read_base *tkr,
|
||||
cycle_t delta)
|
||||
{
|
||||
s64 nsec;
|
||||
u64 nsec;
|
||||
|
||||
nsec = delta * tkr->mult + tkr->xtime_nsec;
|
||||
nsec >>= tkr->shift;
|
||||
@ -311,7 +310,7 @@ static inline s64 timekeeping_delta_to_ns(struct tk_read_base *tkr,
|
||||
return nsec + arch_gettimeoffset();
|
||||
}
|
||||
|
||||
static inline s64 timekeeping_get_ns(struct tk_read_base *tkr)
|
||||
static inline u64 timekeeping_get_ns(struct tk_read_base *tkr)
|
||||
{
|
||||
cycle_t delta;
|
||||
|
||||
@ -319,7 +318,7 @@ static inline s64 timekeeping_get_ns(struct tk_read_base *tkr)
|
||||
return timekeeping_delta_to_ns(tkr, delta);
|
||||
}
|
||||
|
||||
static inline s64 timekeeping_cycles_to_ns(struct tk_read_base *tkr,
|
||||
static inline u64 timekeeping_cycles_to_ns(struct tk_read_base *tkr,
|
||||
cycle_t cycles)
|
||||
{
|
||||
cycle_t delta;
|
||||
@ -425,6 +424,35 @@ u64 ktime_get_raw_fast_ns(void)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ktime_get_raw_fast_ns);
|
||||
|
||||
/**
|
||||
* ktime_get_boot_fast_ns - NMI safe and fast access to boot clock.
|
||||
*
|
||||
* To keep it NMI safe since we're accessing from tracing, we're not using a
|
||||
* separate timekeeper with updates to monotonic clock and boot offset
|
||||
* protected with seqlocks. This has the following minor side effects:
|
||||
*
|
||||
* (1) Its possible that a timestamp be taken after the boot offset is updated
|
||||
* but before the timekeeper is updated. If this happens, the new boot offset
|
||||
* is added to the old timekeeping making the clock appear to update slightly
|
||||
* earlier:
|
||||
* CPU 0 CPU 1
|
||||
* timekeeping_inject_sleeptime64()
|
||||
* __timekeeping_inject_sleeptime(tk, delta);
|
||||
* timestamp();
|
||||
* timekeeping_update(tk, TK_CLEAR_NTP...);
|
||||
*
|
||||
* (2) On 32-bit systems, the 64-bit boot offset (tk->offs_boot) may be
|
||||
* partially updated. Since the tk->offs_boot update is a rare event, this
|
||||
* should be a rare occurrence which postprocessing should be able to handle.
|
||||
*/
|
||||
u64 notrace ktime_get_boot_fast_ns(void)
|
||||
{
|
||||
struct timekeeper *tk = &tk_core.timekeeper;
|
||||
|
||||
return (ktime_get_mono_fast_ns() + ktime_to_ns(tk->offs_boot));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ktime_get_boot_fast_ns);
|
||||
|
||||
/* Suspend-time cycles value for halted fast timekeeper. */
|
||||
static cycle_t cycles_at_suspend;
|
||||
|
||||
@ -623,7 +651,7 @@ static void timekeeping_forward_now(struct timekeeper *tk)
|
||||
{
|
||||
struct clocksource *clock = tk->tkr_mono.clock;
|
||||
cycle_t cycle_now, delta;
|
||||
s64 nsec;
|
||||
u64 nsec;
|
||||
|
||||
cycle_now = tk->tkr_mono.read(clock);
|
||||
delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask);
|
||||
@ -652,7 +680,7 @@ int __getnstimeofday64(struct timespec64 *ts)
|
||||
{
|
||||
struct timekeeper *tk = &tk_core.timekeeper;
|
||||
unsigned long seq;
|
||||
s64 nsecs = 0;
|
||||
u64 nsecs;
|
||||
|
||||
do {
|
||||
seq = read_seqcount_begin(&tk_core.seq);
|
||||
@ -692,7 +720,7 @@ ktime_t ktime_get(void)
|
||||
struct timekeeper *tk = &tk_core.timekeeper;
|
||||
unsigned int seq;
|
||||
ktime_t base;
|
||||
s64 nsecs;
|
||||
u64 nsecs;
|
||||
|
||||
WARN_ON(timekeeping_suspended);
|
||||
|
||||
@ -735,7 +763,7 @@ ktime_t ktime_get_with_offset(enum tk_offsets offs)
|
||||
struct timekeeper *tk = &tk_core.timekeeper;
|
||||
unsigned int seq;
|
||||
ktime_t base, *offset = offsets[offs];
|
||||
s64 nsecs;
|
||||
u64 nsecs;
|
||||
|
||||
WARN_ON(timekeeping_suspended);
|
||||
|
||||
@ -779,7 +807,7 @@ ktime_t ktime_get_raw(void)
|
||||
struct timekeeper *tk = &tk_core.timekeeper;
|
||||
unsigned int seq;
|
||||
ktime_t base;
|
||||
s64 nsecs;
|
||||
u64 nsecs;
|
||||
|
||||
do {
|
||||
seq = read_seqcount_begin(&tk_core.seq);
|
||||
@ -804,8 +832,8 @@ void ktime_get_ts64(struct timespec64 *ts)
|
||||
{
|
||||
struct timekeeper *tk = &tk_core.timekeeper;
|
||||
struct timespec64 tomono;
|
||||
s64 nsec;
|
||||
unsigned int seq;
|
||||
u64 nsec;
|
||||
|
||||
WARN_ON(timekeeping_suspended);
|
||||
|
||||
@ -893,8 +921,8 @@ void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot)
|
||||
unsigned long seq;
|
||||
ktime_t base_raw;
|
||||
ktime_t base_real;
|
||||
s64 nsec_raw;
|
||||
s64 nsec_real;
|
||||
u64 nsec_raw;
|
||||
u64 nsec_real;
|
||||
cycle_t now;
|
||||
|
||||
WARN_ON_ONCE(timekeeping_suspended);
|
||||
@ -1052,7 +1080,7 @@ int get_device_system_crosststamp(int (*get_time_fn)
|
||||
cycle_t cycles, now, interval_start;
|
||||
unsigned int clock_was_set_seq = 0;
|
||||
ktime_t base_real, base_raw;
|
||||
s64 nsec_real, nsec_raw;
|
||||
u64 nsec_real, nsec_raw;
|
||||
u8 cs_was_changed_seq;
|
||||
unsigned long seq;
|
||||
bool do_interp;
|
||||
@ -1365,7 +1393,7 @@ void getrawmonotonic64(struct timespec64 *ts)
|
||||
struct timekeeper *tk = &tk_core.timekeeper;
|
||||
struct timespec64 ts64;
|
||||
unsigned long seq;
|
||||
s64 nsecs;
|
||||
u64 nsecs;
|
||||
|
||||
do {
|
||||
seq = read_seqcount_begin(&tk_core.seq);
|
||||
@ -1616,7 +1644,7 @@ void timekeeping_resume(void)
|
||||
struct clocksource *clock = tk->tkr_mono.clock;
|
||||
unsigned long flags;
|
||||
struct timespec64 ts_new, ts_delta;
|
||||
cycle_t cycle_now, cycle_delta;
|
||||
cycle_t cycle_now;
|
||||
|
||||
sleeptime_injected = false;
|
||||
read_persistent_clock64(&ts_new);
|
||||
@ -1642,27 +1670,11 @@ void timekeeping_resume(void)
|
||||
cycle_now = tk->tkr_mono.read(clock);
|
||||
if ((clock->flags & CLOCK_SOURCE_SUSPEND_NONSTOP) &&
|
||||
cycle_now > tk->tkr_mono.cycle_last) {
|
||||
u64 num, max = ULLONG_MAX;
|
||||
u32 mult = clock->mult;
|
||||
u32 shift = clock->shift;
|
||||
s64 nsec = 0;
|
||||
u64 nsec, cyc_delta;
|
||||
|
||||
cycle_delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last,
|
||||
cyc_delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last,
|
||||
tk->tkr_mono.mask);
|
||||
|
||||
/*
|
||||
* "cycle_delta * mutl" may cause 64 bits overflow, if the
|
||||
* suspended time is too long. In that case we need do the
|
||||
* 64 bits math carefully
|
||||
*/
|
||||
do_div(max, mult);
|
||||
if (cycle_delta > max) {
|
||||
num = div64_u64(cycle_delta, max);
|
||||
nsec = (((u64) max * mult) >> shift) * num;
|
||||
cycle_delta -= num * max;
|
||||
}
|
||||
nsec += ((u64) cycle_delta * mult) >> shift;
|
||||
|
||||
nsec = mul_u64_u32_shr(cyc_delta, clock->mult, clock->shift);
|
||||
ts_delta = ns_to_timespec64(nsec);
|
||||
sleeptime_injected = true;
|
||||
} else if (timespec64_compare(&ts_new, &timekeeping_suspend_time) > 0) {
|
||||
|
@ -1615,6 +1615,7 @@ void update_process_times(int user_tick)
|
||||
irq_work_tick();
|
||||
#endif
|
||||
scheduler_tick();
|
||||
if (IS_ENABLED(CONFIG_POSIX_TIMERS))
|
||||
run_posix_cpu_timers(p);
|
||||
}
|
||||
|
||||
@ -1676,19 +1677,6 @@ void run_local_timers(void)
|
||||
raise_softirq(TIMER_SOFTIRQ);
|
||||
}
|
||||
|
||||
#ifdef __ARCH_WANT_SYS_ALARM
|
||||
|
||||
/*
|
||||
* For backwards compatibility? This can be done in libc so Alpha
|
||||
* and all newer ports shouldn't need it.
|
||||
*/
|
||||
SYSCALL_DEFINE1(alarm, unsigned int, seconds)
|
||||
{
|
||||
return alarm_setitimer(seconds);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void process_timeout(unsigned long __data)
|
||||
{
|
||||
wake_up_process((struct task_struct *)__data);
|
||||
@ -1705,11 +1693,12 @@ static void process_timeout(unsigned long __data)
|
||||
* You can set the task state as follows -
|
||||
*
|
||||
* %TASK_UNINTERRUPTIBLE - at least @timeout jiffies are guaranteed to
|
||||
* pass before the routine returns. The routine will return 0
|
||||
* pass before the routine returns unless the current task is explicitly
|
||||
* woken up, (e.g. by wake_up_process())".
|
||||
*
|
||||
* %TASK_INTERRUPTIBLE - the routine may return early if a signal is
|
||||
* delivered to the current task. In this case the remaining time
|
||||
* in jiffies will be returned, or 0 if the timer expired in time
|
||||
* delivered to the current task or the current task is explicitly woken
|
||||
* up.
|
||||
*
|
||||
* The current task state is guaranteed to be TASK_RUNNING when this
|
||||
* routine returns.
|
||||
@ -1718,7 +1707,9 @@ static void process_timeout(unsigned long __data)
|
||||
* the CPU away without a bound on the timeout. In this case the return
|
||||
* value will be %MAX_SCHEDULE_TIMEOUT.
|
||||
*
|
||||
* In all cases the return value is guaranteed to be non-negative.
|
||||
* Returns 0 when the timer has expired otherwise the remaining time in
|
||||
* jiffies will be returned. In all cases the return value is guaranteed
|
||||
* to be non-negative.
|
||||
*/
|
||||
signed long __sched schedule_timeout(signed long timeout)
|
||||
{
|
||||
@ -1910,16 +1901,6 @@ unsigned long msleep_interruptible(unsigned int msecs)
|
||||
|
||||
EXPORT_SYMBOL(msleep_interruptible);
|
||||
|
||||
static void __sched do_usleep_range(unsigned long min, unsigned long max)
|
||||
{
|
||||
ktime_t kmin;
|
||||
u64 delta;
|
||||
|
||||
kmin = ktime_set(0, min * NSEC_PER_USEC);
|
||||
delta = (u64)(max - min) * NSEC_PER_USEC;
|
||||
schedule_hrtimeout_range(&kmin, delta, HRTIMER_MODE_REL);
|
||||
}
|
||||
|
||||
/**
|
||||
* usleep_range - Sleep for an approximate time
|
||||
* @min: Minimum time in usecs to sleep
|
||||
@ -1933,7 +1914,14 @@ static void __sched do_usleep_range(unsigned long min, unsigned long max)
|
||||
*/
|
||||
void __sched usleep_range(unsigned long min, unsigned long max)
|
||||
{
|
||||
ktime_t exp = ktime_add_us(ktime_get(), min);
|
||||
u64 delta = (u64)(max - min) * NSEC_PER_USEC;
|
||||
|
||||
for (;;) {
|
||||
__set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
do_usleep_range(min, max);
|
||||
/* Do not return before the requested sleep time has elapsed */
|
||||
if (!schedule_hrtimeout_range(&exp, delta, HRTIMER_MODE_ABS))
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(usleep_range);
|
||||
|
@ -1125,6 +1125,7 @@ static struct {
|
||||
{ trace_clock, "perf", 1 },
|
||||
{ ktime_get_mono_fast_ns, "mono", 1 },
|
||||
{ ktime_get_raw_fast_ns, "mono_raw", 1 },
|
||||
{ ktime_get_boot_fast_ns, "boot", 1 },
|
||||
ARCH_TRACE_CLOCKS
|
||||
};
|
||||
|
||||
|
@ -85,6 +85,7 @@ struct symbol {
|
||||
struct property *prop;
|
||||
struct expr_value dir_dep;
|
||||
struct expr_value rev_dep;
|
||||
struct expr_value implied;
|
||||
};
|
||||
|
||||
#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
|
||||
@ -136,6 +137,7 @@ enum prop_type {
|
||||
P_DEFAULT, /* default y */
|
||||
P_CHOICE, /* choice value */
|
||||
P_SELECT, /* select BAR */
|
||||
P_IMPLY, /* imply BAR */
|
||||
P_RANGE, /* range 7..100 (for a symbol) */
|
||||
P_ENV, /* value from environment variable */
|
||||
P_SYMBOL, /* where a symbol is defined */
|
||||
|
@ -233,6 +233,8 @@ static void sym_check_prop(struct symbol *sym)
|
||||
{
|
||||
struct property *prop;
|
||||
struct symbol *sym2;
|
||||
char *use;
|
||||
|
||||
for (prop = sym->prop; prop; prop = prop->next) {
|
||||
switch (prop->type) {
|
||||
case P_DEFAULT:
|
||||
@ -252,18 +254,20 @@ static void sym_check_prop(struct symbol *sym)
|
||||
}
|
||||
break;
|
||||
case P_SELECT:
|
||||
case P_IMPLY:
|
||||
use = prop->type == P_SELECT ? "select" : "imply";
|
||||
sym2 = prop_get_symbol(prop);
|
||||
if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
|
||||
prop_warn(prop,
|
||||
"config symbol '%s' uses select, but is "
|
||||
"not boolean or tristate", sym->name);
|
||||
"config symbol '%s' uses %s, but is "
|
||||
"not boolean or tristate", sym->name, use);
|
||||
else if (sym2->type != S_UNKNOWN &&
|
||||
sym2->type != S_BOOLEAN &&
|
||||
sym2->type != S_TRISTATE)
|
||||
prop_warn(prop,
|
||||
"'%s' has wrong type. 'select' only "
|
||||
"'%s' has wrong type. '%s' only "
|
||||
"accept arguments of boolean and "
|
||||
"tristate type", sym2->name);
|
||||
"tristate type", sym2->name, use);
|
||||
break;
|
||||
case P_RANGE:
|
||||
if (sym->type != S_INT && sym->type != S_HEX)
|
||||
@ -333,6 +337,10 @@ void menu_finalize(struct menu *parent)
|
||||
struct symbol *es = prop_get_symbol(prop);
|
||||
es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
|
||||
expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
|
||||
} else if (prop->type == P_IMPLY) {
|
||||
struct symbol *es = prop_get_symbol(prop);
|
||||
es->implied.expr = expr_alloc_or(es->implied.expr,
|
||||
expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -612,13 +620,30 @@ static struct property *get_symbol_prop(struct symbol *sym)
|
||||
return prop;
|
||||
}
|
||||
|
||||
static void get_symbol_props_str(struct gstr *r, struct symbol *sym,
|
||||
enum prop_type tok, const char *prefix)
|
||||
{
|
||||
bool hit = false;
|
||||
struct property *prop;
|
||||
|
||||
for_all_properties(sym, prop, tok) {
|
||||
if (!hit) {
|
||||
str_append(r, prefix);
|
||||
hit = true;
|
||||
} else
|
||||
str_printf(r, " && ");
|
||||
expr_gstr_print(prop->expr, r);
|
||||
}
|
||||
if (hit)
|
||||
str_append(r, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* head is optional and may be NULL
|
||||
*/
|
||||
static void get_symbol_str(struct gstr *r, struct symbol *sym,
|
||||
struct list_head *head)
|
||||
{
|
||||
bool hit;
|
||||
struct property *prop;
|
||||
|
||||
if (sym && sym->name) {
|
||||
@ -648,22 +673,20 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym,
|
||||
}
|
||||
}
|
||||
|
||||
hit = false;
|
||||
for_all_properties(sym, prop, P_SELECT) {
|
||||
if (!hit) {
|
||||
str_append(r, " Selects: ");
|
||||
hit = true;
|
||||
} else
|
||||
str_printf(r, " && ");
|
||||
expr_gstr_print(prop->expr, r);
|
||||
}
|
||||
if (hit)
|
||||
str_append(r, "\n");
|
||||
get_symbol_props_str(r, sym, P_SELECT, _(" Selects: "));
|
||||
if (sym->rev_dep.expr) {
|
||||
str_append(r, _(" Selected by: "));
|
||||
expr_gstr_print(sym->rev_dep.expr, r);
|
||||
str_append(r, "\n");
|
||||
}
|
||||
|
||||
get_symbol_props_str(r, sym, P_IMPLY, _(" Implies: "));
|
||||
if (sym->implied.expr) {
|
||||
str_append(r, _(" Implied by: "));
|
||||
expr_gstr_print(sym->implied.expr, r);
|
||||
str_append(r, "\n");
|
||||
}
|
||||
|
||||
str_append(r, "\n\n");
|
||||
}
|
||||
|
||||
|
@ -258,6 +258,15 @@ static void sym_calc_visibility(struct symbol *sym)
|
||||
sym->rev_dep.tri = tri;
|
||||
sym_set_changed(sym);
|
||||
}
|
||||
tri = no;
|
||||
if (sym->implied.expr && sym->dir_dep.tri != no)
|
||||
tri = expr_calc_value(sym->implied.expr);
|
||||
if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
|
||||
tri = yes;
|
||||
if (sym->implied.tri != tri) {
|
||||
sym->implied.tri = tri;
|
||||
sym_set_changed(sym);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -397,6 +406,10 @@ void sym_calc_value(struct symbol *sym)
|
||||
newval.tri = EXPR_AND(expr_calc_value(prop->expr),
|
||||
prop->visible.tri);
|
||||
}
|
||||
if (sym->implied.tri != no) {
|
||||
sym->flags |= SYMBOL_WRITE;
|
||||
newval.tri = EXPR_OR(newval.tri, sym->implied.tri);
|
||||
}
|
||||
}
|
||||
calc_newval:
|
||||
if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
|
||||
@ -413,7 +426,8 @@ void sym_calc_value(struct symbol *sym)
|
||||
}
|
||||
newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
|
||||
}
|
||||
if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
|
||||
if (newval.tri == mod &&
|
||||
(sym_get_type(sym) == S_BOOLEAN || sym->implied.tri == yes))
|
||||
newval.tri = yes;
|
||||
break;
|
||||
case S_STRING:
|
||||
@ -498,6 +512,8 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val)
|
||||
return false;
|
||||
if (sym->visible <= sym->rev_dep.tri)
|
||||
return false;
|
||||
if (sym->implied.tri == yes && val == mod)
|
||||
return false;
|
||||
if (sym_is_choice_value(sym) && sym->visible == yes)
|
||||
return val == yes;
|
||||
return val >= sym->rev_dep.tri && val <= sym->visible;
|
||||
@ -750,6 +766,10 @@ const char *sym_get_string_default(struct symbol *sym)
|
||||
if (sym->type == S_BOOLEAN && val == mod)
|
||||
val = yes;
|
||||
|
||||
/* adjust the default value if this symbol is implied by another */
|
||||
if (val < sym->implied.tri)
|
||||
val = sym->implied.tri;
|
||||
|
||||
switch (sym->type) {
|
||||
case S_BOOLEAN:
|
||||
case S_TRISTATE:
|
||||
@ -1352,6 +1372,8 @@ const char *prop_get_type_name(enum prop_type type)
|
||||
return "choice";
|
||||
case P_SELECT:
|
||||
return "select";
|
||||
case P_IMPLY:
|
||||
return "imply";
|
||||
case P_RANGE:
|
||||
return "range";
|
||||
case P_SYMBOL:
|
||||
|
@ -38,6 +38,7 @@ int, T_TYPE, TF_COMMAND, S_INT
|
||||
hex, T_TYPE, TF_COMMAND, S_HEX
|
||||
string, T_TYPE, TF_COMMAND, S_STRING
|
||||
select, T_SELECT, TF_COMMAND
|
||||
imply, T_IMPLY, TF_COMMAND
|
||||
range, T_RANGE, TF_COMMAND
|
||||
visible, T_VISIBLE, TF_COMMAND
|
||||
option, T_OPTION, TF_COMMAND
|
||||
|
@ -55,10 +55,10 @@ kconf_id_hash (register const char *str, register unsigned int len)
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 5, 25, 25,
|
||||
73, 73, 73, 73, 73, 73, 73, 10, 25, 25,
|
||||
0, 0, 0, 5, 0, 0, 73, 73, 5, 0,
|
||||
10, 5, 45, 73, 20, 20, 0, 15, 15, 73,
|
||||
20, 5, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
20, 0, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
@ -120,6 +120,7 @@ struct kconf_id_strings_t
|
||||
char kconf_id_strings_str43[sizeof("hex")];
|
||||
char kconf_id_strings_str46[sizeof("config")];
|
||||
char kconf_id_strings_str47[sizeof("boolean")];
|
||||
char kconf_id_strings_str50[sizeof("imply")];
|
||||
char kconf_id_strings_str51[sizeof("string")];
|
||||
char kconf_id_strings_str54[sizeof("help")];
|
||||
char kconf_id_strings_str56[sizeof("prompt")];
|
||||
@ -157,6 +158,7 @@ static const struct kconf_id_strings_t kconf_id_strings_contents =
|
||||
"hex",
|
||||
"config",
|
||||
"boolean",
|
||||
"imply",
|
||||
"string",
|
||||
"help",
|
||||
"prompt",
|
||||
@ -174,7 +176,7 @@ kconf_id_lookup (register const char *str, register unsigned int len)
|
||||
{
|
||||
enum
|
||||
{
|
||||
TOTAL_KEYWORDS = 34,
|
||||
TOTAL_KEYWORDS = 35,
|
||||
MIN_WORD_LENGTH = 2,
|
||||
MAX_WORD_LENGTH = 14,
|
||||
MIN_HASH_VALUE = 2,
|
||||
@ -205,15 +207,15 @@ kconf_id_lookup (register const char *str, register unsigned int len)
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_TRISTATE},
|
||||
#line 36 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
|
||||
#line 46 "scripts/kconfig/zconf.gperf"
|
||||
#line 47 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_OPT_DEFCONFIG_LIST,TF_OPTION},
|
||||
{-1}, {-1},
|
||||
#line 44 "scripts/kconfig/zconf.gperf"
|
||||
#line 45 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_ON, TF_PARAM},
|
||||
#line 29 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_OPTIONAL, TF_COMMAND},
|
||||
{-1}, {-1},
|
||||
#line 43 "scripts/kconfig/zconf.gperf"
|
||||
#line 44 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_OPTION, TF_COMMAND},
|
||||
#line 17 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ENDMENU, TF_COMMAND},
|
||||
@ -223,9 +225,9 @@ kconf_id_lookup (register const char *str, register unsigned int len)
|
||||
#line 23 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str25, T_MENUCONFIG, TF_COMMAND},
|
||||
{-1},
|
||||
#line 45 "scripts/kconfig/zconf.gperf"
|
||||
#line 46 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION},
|
||||
#line 48 "scripts/kconfig/zconf.gperf"
|
||||
#line 49 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_OPT_ALLNOCONFIG_Y,TF_OPTION},
|
||||
#line 16 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND},
|
||||
@ -234,10 +236,10 @@ kconf_id_lookup (register const char *str, register unsigned int len)
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SELECT, TF_COMMAND},
|
||||
#line 21 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND},
|
||||
#line 47 "scripts/kconfig/zconf.gperf"
|
||||
#line 48 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_OPT_ENV, TF_OPTION},
|
||||
{-1},
|
||||
#line 41 "scripts/kconfig/zconf.gperf"
|
||||
#line 42 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_RANGE, TF_COMMAND},
|
||||
#line 19 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_CHOICE, TF_COMMAND},
|
||||
@ -247,7 +249,7 @@ kconf_id_lookup (register const char *str, register unsigned int len)
|
||||
{-1},
|
||||
#line 18 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_SOURCE, TF_COMMAND},
|
||||
#line 42 "scripts/kconfig/zconf.gperf"
|
||||
#line 43 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_VISIBLE, TF_COMMAND},
|
||||
#line 38 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str43, T_TYPE, TF_COMMAND, S_HEX},
|
||||
@ -256,7 +258,9 @@ kconf_id_lookup (register const char *str, register unsigned int len)
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_CONFIG, TF_COMMAND},
|
||||
#line 35 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47, T_TYPE, TF_COMMAND, S_BOOLEAN},
|
||||
{-1}, {-1}, {-1},
|
||||
{-1}, {-1},
|
||||
#line 41 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str50, T_IMPLY, TF_COMMAND},
|
||||
#line 39 "scripts/kconfig/zconf.gperf"
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str51, T_TYPE, TF_COMMAND, S_STRING},
|
||||
{-1}, {-1},
|
||||
@ -289,5 +293,5 @@ kconf_id_lookup (register const char *str, register unsigned int len)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#line 49 "scripts/kconfig/zconf.gperf"
|
||||
#line 50 "scripts/kconfig/zconf.gperf"
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -31,7 +31,7 @@ struct symbol *symbol_hash[SYMBOL_HASHSIZE];
|
||||
static struct menu *current_menu, *current_entry;
|
||||
|
||||
%}
|
||||
%expect 30
|
||||
%expect 32
|
||||
|
||||
%union
|
||||
{
|
||||
@ -62,6 +62,7 @@ static struct menu *current_menu, *current_entry;
|
||||
%token <id>T_TYPE
|
||||
%token <id>T_DEFAULT
|
||||
%token <id>T_SELECT
|
||||
%token <id>T_IMPLY
|
||||
%token <id>T_RANGE
|
||||
%token <id>T_VISIBLE
|
||||
%token <id>T_OPTION
|
||||
@ -124,7 +125,7 @@ stmt_list:
|
||||
;
|
||||
|
||||
option_name:
|
||||
T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE
|
||||
T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_IMPLY | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE
|
||||
;
|
||||
|
||||
common_stmt:
|
||||
@ -216,6 +217,12 @@ config_option: T_SELECT T_WORD if_expr T_EOL
|
||||
printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
|
||||
};
|
||||
|
||||
config_option: T_IMPLY T_WORD if_expr T_EOL
|
||||
{
|
||||
menu_add_symbol(P_IMPLY, sym_lookup($2, 0), $3);
|
||||
printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno());
|
||||
};
|
||||
|
||||
config_option: T_RANGE symbol symbol if_expr T_EOL
|
||||
{
|
||||
menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
|
||||
@ -664,6 +671,11 @@ static void print_symbol(FILE *out, struct menu *menu)
|
||||
expr_fprint(prop->expr, out);
|
||||
fputc('\n', out);
|
||||
break;
|
||||
case P_IMPLY:
|
||||
fputs( " imply ", out);
|
||||
expr_fprint(prop->expr, out);
|
||||
fputc('\n', out);
|
||||
break;
|
||||
case P_RANGE:
|
||||
fputs( " range ", out);
|
||||
expr_fprint(prop->expr, out);
|
||||
|
@ -2525,6 +2525,7 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
|
||||
rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
|
||||
}
|
||||
task_unlock(current);
|
||||
if (IS_ENABLED(CONFIG_POSIX_TIMERS))
|
||||
update_rlimit_cpu(current, rlimit(RLIMIT_CPU));
|
||||
}
|
||||
}
|
||||
@ -2555,9 +2556,11 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
|
||||
*/
|
||||
rc = avc_has_perm(osid, sid, SECCLASS_PROCESS, PROCESS__SIGINH, NULL);
|
||||
if (rc) {
|
||||
if (IS_ENABLED(CONFIG_POSIX_TIMERS)) {
|
||||
memset(&itimer, 0, sizeof itimer);
|
||||
for (i = 0; i < 3; i++)
|
||||
do_setitimer(i, &itimer, NULL);
|
||||
}
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
if (!fatal_signal_pending(current)) {
|
||||
flush_sigqueue(¤t->pending);
|
||||
|
@ -57,7 +57,7 @@ int main(int argv, char **argc)
|
||||
pid_t pid;
|
||||
|
||||
|
||||
printf("Running Asyncrhonous Frequency Changing Tests...\n");
|
||||
printf("Running Asynchronous Frequency Changing Tests...\n");
|
||||
|
||||
pid = fork();
|
||||
if (!pid)
|
||||
|
Loading…
Reference in New Issue
Block a user