[PATCH v2 04/10] mmc: sunxi: Support controllers that can use both old and new timings
On the SoCs that introduced the new timing mode for MMC controllers, both the old (where the clock delays are set in the CCU) and new (where the clock delays are set in the MMC controller) timing modes are available, and we have to support them both. However there are two bits that control which mode is active. One is in the CCU, the other is in the MMC controller. The settings on both sides must be the same, or nothing will work. The sunxi-ng clock driver provides an API to query and set the active timing mode. At probe time, we try to set the active mode to the "new timing mode". If it succeeds, we can then use the MMC controller in the new mode. If not, we fall back to the old mode. Signed-off-by: Chen-Yu Tsai --- drivers/mmc/host/sunxi-mmc.c | 45 ++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c index 0fb4e4c119e1..c8a60e43dc43 100644 --- a/drivers/mmc/host/sunxi-mmc.c +++ b/drivers/mmc/host/sunxi-mmc.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -259,7 +260,11 @@ struct sunxi_mmc_cfg { /* Does DATA0 needs to be masked while the clock is updated */ bool mask_data0; + /* hardware only supports new timing mode */ bool needs_new_timings; + + /* hardware can switch between old and new timing modes */ + bool has_timings_switch; }; struct sunxi_mmc_host { @@ -293,6 +298,9 @@ struct sunxi_mmc_host { /* vqmmc */ boolvqmmc_enabled; + + /* timings */ + booluse_new_timings; }; static int sunxi_mmc_reset_host(struct sunxi_mmc_host *host) @@ -714,7 +722,7 @@ static int sunxi_mmc_clk_set_phase(struct sunxi_mmc_host *host, { int index; - if (!host->cfg->clk_delays) + if (host->use_new_timings) return 0; /* determine delays */ @@ -765,6 +773,15 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, ios->bus_width == MMC_BUS_WIDTH_8) clock <<= 1; + if (host->use_new_timings) { + ret = sunxi_ccu_set_mmc_timing_mode(host->clk_mmc, true); + if (ret) { + dev_err(mmc_dev(mmc), + "error setting new timing mode\n"); + return ret; + } + } + rate = clk_round_rate(host->clk_mmc, clock); if (rate < 0) { dev_err(mmc_dev(mmc), "error rounding clk to %d: %ld\n", @@ -793,7 +810,7 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, } mmc_writel(host, REG_CLKCR, rval); - if (host->cfg->needs_new_timings) { + if (host->use_new_timings) { /* Don't touch the delay bits */ rval = mmc_readl(host, REG_SD_NTSR); rval |= SDXC_2X_TIMING_MODE; @@ -1262,6 +1279,30 @@ static int sunxi_mmc_probe(struct platform_device *pdev) goto error_free_host; } + if (host->cfg->has_timings_switch) { + /* +* Supports both old and new timing modes. +* Try setting the clk to new timing mode. +*/ + sunxi_ccu_set_mmc_timing_mode(host->clk_mmc, true); + + /* And check the result */ + ret = sunxi_ccu_get_mmc_timing_mode(host->clk_mmc); + if (ret < 0) { + /* +* For whatever reason we were not able to get +* the current active mode. Default to old mode. +*/ + dev_warn(&pdev->dev, "MMC clk timing mode unknown\n"); + host->use_new_timings = false; + } else { + host->use_new_timings = !!ret; + } + } else if (host->cfg->needs_new_timings) { + /* Supports new timing mode only */ + host->use_new_timings = true; + } + mmc->ops= &sunxi_mmc_ops; mmc->max_blk_count = 8192; mmc->max_blk_size = 4096; -- 2.13.2
[PATCH v2 06/10] mmc: sunxi: Add support for A83T eMMC (MMC2)
The third MMC controller (MMC2) on the Allwinner A83T SoC is slightly different. It supports a wider 8-bit bus, has a dedicated controllable reset pin for eMMC, and a "new timing mode" which is supposed to deliver better signals and thus better performance. Add a compatible for this one to use the new timing mode not found in the other controllers. Signed-off-by: Chen-Yu Tsai Acked-by: Rob Herring --- Documentation/devicetree/bindings/mmc/sunxi-mmc.txt | 1 + drivers/mmc/host/sunxi-mmc.c| 8 2 files changed, 9 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt b/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt index 7d53a799f140..63b57e2a10fb 100644 --- a/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt +++ b/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt @@ -12,6 +12,7 @@ Required properties: * "allwinner,sun4i-a10-mmc" * "allwinner,sun5i-a13-mmc" * "allwinner,sun7i-a20-mmc" + * "allwinner,sun8i-a83t-emmc" * "allwinner,sun9i-a80-mmc" * "allwinner,sun50i-a64-emmc" * "allwinner,sun50i-a64-mmc" diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c index 11587a69a1fd..de187ed77040 100644 --- a/drivers/mmc/host/sunxi-mmc.c +++ b/drivers/mmc/host/sunxi-mmc.c @@ -1117,6 +1117,13 @@ static const struct sunxi_mmc_cfg sun7i_a20_cfg = { .can_calibrate = false, }; +static const struct sunxi_mmc_cfg sun8i_a83t_emmc_cfg = { + .idma_des_size_bits = 16, + .clk_delays = sunxi_mmc_clk_delays, + .can_calibrate = false, + .has_timings_switch = true, +}; + static const struct sunxi_mmc_cfg sun9i_a80_cfg = { .idma_des_size_bits = 16, .clk_delays = sun9i_mmc_clk_delays, @@ -1141,6 +1148,7 @@ static const struct of_device_id sunxi_mmc_of_match[] = { { .compatible = "allwinner,sun4i-a10-mmc", .data = &sun4i_a10_cfg }, { .compatible = "allwinner,sun5i-a13-mmc", .data = &sun5i_a13_cfg }, { .compatible = "allwinner,sun7i-a20-mmc", .data = &sun7i_a20_cfg }, + { .compatible = "allwinner,sun8i-a83t-emmc", .data = &sun8i_a83t_emmc_cfg }, { .compatible = "allwinner,sun9i-a80-mmc", .data = &sun9i_a80_cfg }, { .compatible = "allwinner,sun50i-a64-mmc", .data = &sun50i_a64_cfg }, { .compatible = "allwinner,sun50i-a64-emmc", .data = &sun50i_a64_emmc_cfg }, -- 2.13.2
[PATCH v2 09/10] ARM: dts: sun8i: a83t: cubietruck-plus: Enable micro-SD card and eMMC
Now that we support the MMC controllers on the A83T SoC, we can enable them on some boards. Signed-off-by: Chen-Yu Tsai --- arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts | 27 1 file changed, 27 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts index cff33454fc24..163ddf8868b5 100644 --- a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts +++ b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts @@ -83,6 +83,13 @@ }; }; + reg_vcc3v3: vcc3v3 { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + }; + sound { compatible = "simple-audio-card"; simple-audio-card,name = "On-board SPDIF"; @@ -102,6 +109,26 @@ }; }; +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ + cd-inverted; + status = "okay"; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_8bit_emmc_pins>; + vmmc-supply = <®_vcc3v3>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + status = "okay"; +}; + &spdif { status = "okay"; }; -- 2.13.2
[PATCH v2 10/10] ARM: dts: sun8i: a83t: h8homlet: Enable micro-SD card and onboard eMMC
The H8 homlet has a micro-SD card slot connected to mmc0, and onboard eMMC from FORESEE, connected to mmc2. Signed-off-by: Chen-Yu Tsai --- .../boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts | 21 + 1 file changed, 21 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts index aecdeeb368ed..7afbaa4eea8d 100644 --- a/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts +++ b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts @@ -43,6 +43,7 @@ /dts-v1/; #include "sun8i-a83t.dtsi" +#include "sunxi-common-regulators.dtsi" / { model = "Allwinner A83T H8Homlet Proto Dev Board v2.0"; @@ -57,6 +58,26 @@ }; }; +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <®_vcc3v0>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ + bus-width = <4>; + cd-inverted; + status = "okay"; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_8bit_emmc_pins>; + vmmc-supply = <®_vcc3v0>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pb_pins>; -- 2.13.2
[PATCH v2 05/10] mmc: sunxi: Support MMC DDR52 transfer mode with new timing mode
The MMC controller can support DDR52 transfers under the new timing mode. According to the BSP kernel, the module clock has to be double the card clock, regardless of the bus width. The default timings in the hardware can be used. This also reworks the code setting the internal divider, getting rid of a extra conditional. Signed-off-by: Chen-Yu Tsai --- drivers/mmc/host/sunxi-mmc.c | 30 ++ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c index c8a60e43dc43..11587a69a1fd 100644 --- a/drivers/mmc/host/sunxi-mmc.c +++ b/drivers/mmc/host/sunxi-mmc.c @@ -755,7 +755,7 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, { struct mmc_host *mmc = host->mmc; long rate; - u32 rval, clock = ios->clock; + u32 rval, clock = ios->clock, div = 1; int ret; ret = sunxi_mmc_oclk_onoff(host, 0); @@ -768,10 +768,21 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, if (!ios->clock) return 0; - /* 8 bit DDR requires a higher module clock */ + /* +* Under the old timing mode, 8 bit DDR requires the module +* clock to be double the card clock. Under the new timing +* mode, all DDR modes require a doubled module clock. +* +* We currently only support the standard MMC DDR52 mode. +* This block should be updated once support for other DDR +* modes is added. +*/ if (ios->timing == MMC_TIMING_MMC_DDR52 && - ios->bus_width == MMC_BUS_WIDTH_8) + (host->use_new_timings || +ios->bus_width == MMC_BUS_WIDTH_8)) { + div = 2; clock <<= 1; + } if (host->use_new_timings) { ret = sunxi_ccu_set_mmc_timing_mode(host->clk_mmc, true); @@ -799,15 +810,10 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, return ret; } - /* clear internal divider */ + /* set internal divider */ rval = mmc_readl(host, REG_CLKCR); rval &= ~0xff; - /* set internal divider for 8 bit eMMC DDR, so card clock is right */ - if (ios->timing == MMC_TIMING_MMC_DDR52 && - ios->bus_width == MMC_BUS_WIDTH_8) { - rval |= 1; - rate >>= 1; - } + rval |= div - 1; mmc_writel(host, REG_CLKCR, rval); if (host->use_new_timings) { @@ -838,7 +844,7 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, return ret; /* And we just enabled our clock back */ - mmc->actual_clock = rate; + mmc->actual_clock = rate / div; return 0; } @@ -1315,7 +1321,7 @@ static int sunxi_mmc_probe(struct platform_device *pdev) mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ; - if (host->cfg->clk_delays) + if (host->cfg->clk_delays || host->use_new_timings) mmc->caps |= MMC_CAP_1_8V_DDR; ret = mmc_of_parse(mmc); -- 2.13.2
[PATCH v2 03/10] clk: sunxi-ng: a83t: Support new timing mode for mmc2 clock
The MMC2 clock supports a new timing mode. When the new mode is active, the output clock rate is halved. This patch sets the feature flag for the new timing mode, and adds a pre-divider based on the mode bit. Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu-sun8i-a83t.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c index 947f9f6e05d2..c5656e4f2a38 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c @@ -418,14 +418,13 @@ static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1-sample", "mmc1", static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1-output", "mmc1", 0x08c, 8, 3, 0); -/* TODO Support MMC2 clock's new timing mode. */ -static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, - 0x090, - 0, 4, /* M */ - 16, 2,/* P */ - 24, 2,/* mux */ - BIT(31), /* gate */ - 0); +static SUNXI_CCU_MP_MMC_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, + 0x090, + 0, 4, /* M */ + 16, 2,/* P */ + 24, 2,/* mux */ + BIT(31), /* gate */ + CLK_GET_RATE_NOCACHE); static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2-sample", "mmc2", 0x090, 20, 3, 0); -- 2.13.2
[PATCH v2 02/10] clk: sunxi-ng: Add MP_MMC clocks that support MMC timing modes switching
All of our MMC clocks are of the MP clock type. A few MMC clocks on some SoCs, such as MMC2 on the A83T, support new/old timing mode switching. >From a clock rate point of view, when the new timing mode is active. the output clock rate is halved. This patch adds a special wrapper class of clocks, MP_MMC, around the generic MP type clocks. The rate related callbacks in ccu_mp_mmc_ops for this class look at the timing mode bit and apply the /2 post-divider when needed, before passing it through to the generic class ops, ccu_mp_ops. Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu_mp.c | 80 +++ drivers/clk/sunxi-ng/ccu_mp.h | 24 + 2 files changed, 104 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c index b917ad7a386c..688855e7dc8c 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.c +++ b/drivers/clk/sunxi-ng/ccu_mp.c @@ -172,3 +172,83 @@ const struct clk_ops ccu_mp_ops = { .recalc_rate= ccu_mp_recalc_rate, .set_rate = ccu_mp_set_rate, }; + +/* + * Support for MMC timing mode switching + * + * The MMC clocks on some SoCs support switching between old and + * new timing modes. A platform specific API is provided to query + * and set the timing mode on supported SoCs. + * + * In addition, a special class of ccu_mp_ops is provided, which + * takes in to account the timing mode switch. When the new timing + * mode is active, the clock output rate is halved. This new class + * is a wrapper around the generic ccu_mp_ops. When clock rates + * are passed through to ccu_mp_ops callbacks, they are doubled + * if the new timing mode bit is set, to account for the post + * divider. Conversely, when clock rates are passed back, they + * are halved if the mode bit is set. + */ + +static unsigned long ccu_mp_mmc_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + unsigned long rate = ccu_mp_recalc_rate(hw, parent_rate); + struct ccu_common *cm = hw_to_ccu_common(hw); + u32 val = readl(cm->base + cm->reg); + + if (val & CCU_MMC_NEW_TIMING_MODE) + return rate / 2; + return rate; +} + +static int ccu_mp_mmc_determine_rate(struct clk_hw *hw, +struct clk_rate_request *req) +{ + struct ccu_common *cm = hw_to_ccu_common(hw); + u32 val = readl(cm->base + cm->reg); + int ret; + + /* adjust the requested clock rate */ + if (val & CCU_MMC_NEW_TIMING_MODE) { + req->rate *= 2; + req->min_rate *= 2; + req->max_rate *= 2; + } + + ret = ccu_mp_determine_rate(hw, req); + + /* re-adjust the requested clock rate back */ + if (val & CCU_MMC_NEW_TIMING_MODE) { + req->rate /= 2; + req->min_rate /= 2; + req->max_rate /= 2; + } + + return ret; +} + +static int ccu_mp_mmc_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct ccu_common *cm = hw_to_ccu_common(hw); + u32 val = readl(cm->base + cm->reg); + + if (val & CCU_MMC_NEW_TIMING_MODE) + rate *= 2; + + return ccu_mp_set_rate(hw, rate, parent_rate); +} + +const struct clk_ops ccu_mp_mmc_ops = { + .disable= ccu_mp_disable, + .enable = ccu_mp_enable, + .is_enabled = ccu_mp_is_enabled, + + .get_parent = ccu_mp_get_parent, + .set_parent = ccu_mp_set_parent, + + .determine_rate = ccu_mp_mmc_determine_rate, + .recalc_rate= ccu_mp_mmc_recalc_rate, + .set_rate = ccu_mp_mmc_set_rate, +}; diff --git a/drivers/clk/sunxi-ng/ccu_mp.h b/drivers/clk/sunxi-ng/ccu_mp.h index 915625e97d98..e5e90cec648e 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.h +++ b/drivers/clk/sunxi-ng/ccu_mp.h @@ -74,4 +74,28 @@ static inline struct ccu_mp *hw_to_ccu_mp(struct clk_hw *hw) extern const struct clk_ops ccu_mp_ops; +/* Special class of M-P clock that supports MMC timing modes */ + +#define SUNXI_CCU_MP_MMC_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ + _mshift, _mwidth,\ + _pshift, _pwidth,\ + _muxshift, _muxwidth,\ + _gate, _flags) \ + struct ccu_mp _struct = { \ + .enable = _gate,\ + .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ + .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \ + .mux= _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ + .common = { \ + .reg= _reg,
[PATCH v2 01/10] clk: sunxi-ng: Add interface to query or configure MMC timing modes.
Starting with the A83T SoC, Allwinner introduced a new timing mode for its MMC clocks. The new mode changes how the MMC controller sample and output clocks are delayed to match chip and board specifics. There are two controls for this, one on the CCU side controlling how the clocks behave, and one in the MMC controller controlling what inputs to take and how to route them. In the old mode, the MMC clock had 2 child clocks providing the output and sample clocks, which could be delayed by a number of clock cycles measured from the MMC clock's parent. With the new mode, the 2 delay clocks are no longer active. Instead, the delays and associated controls are moved into the MMC controller. The output of the MMC clock is also halved. The difference in how things are wired between the modes means that the clock controls and the MMC controls must match. To achieve this in a clear, explicit way, we introduce two functions for the MMC driver to use: one queries the hardware for the current mode set, and the other allows the MMC driver to request a mode. Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/Makefile | 1 + drivers/clk/sunxi-ng/ccu_common.h | 5 +++ drivers/clk/sunxi-ng/ccu_mmc_timing.c | 73 +++ include/linux/clk/sunxi-ng.h | 35 + 4 files changed, 114 insertions(+) create mode 100644 drivers/clk/sunxi-ng/ccu_mmc_timing.c create mode 100644 include/linux/clk/sunxi-ng.h diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile index 0c45fa50283d..45a5910379a5 100644 --- a/drivers/clk/sunxi-ng/Makefile +++ b/drivers/clk/sunxi-ng/Makefile @@ -1,5 +1,6 @@ # Common objects lib-$(CONFIG_SUNXI_CCU)+= ccu_common.o +lib-$(CONFIG_SUNXI_CCU)+= ccu_mmc_timing.o lib-$(CONFIG_SUNXI_CCU)+= ccu_reset.o # Base clock types diff --git a/drivers/clk/sunxi-ng/ccu_common.h b/drivers/clk/sunxi-ng/ccu_common.h index d6fdd7a789aa..1e2761c53f06 100644 --- a/drivers/clk/sunxi-ng/ccu_common.h +++ b/drivers/clk/sunxi-ng/ccu_common.h @@ -23,6 +23,11 @@ #define CCU_FEATURE_FIXED_POSTDIV BIT(3) #define CCU_FEATURE_ALL_PREDIV BIT(4) #define CCU_FEATURE_LOCK_REG BIT(5) +#define CCU_FEATURE_MMC_TIMING_SWITCH BIT(6) +#define CCU_FEATURE_MMC_ALWAYS_NEW BIT(7) + +/* MMC timing mode switch bit */ +#define CCU_MMC_NEW_TIMING_MODEBIT(30) struct device_node; diff --git a/drivers/clk/sunxi-ng/ccu_mmc_timing.c b/drivers/clk/sunxi-ng/ccu_mmc_timing.c new file mode 100644 index ..c5e86061c613 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu_mmc_timing.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2017 Chen-Yu Tsai. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#include "ccu_common.h" + +/** + * sunxi_ccu_set_mmc_timing_mode: Configure the MMC clock timing mode + * @clk: clock to be configured + * @new_mode: true for new timing mode introduced in A83T and later + * + * Returns 0 on success, -ENOTSUPP if the clock does not support + * switching modes. + */ +int sunxi_ccu_set_mmc_timing_mode(struct clk *clk, bool new_mode) +{ + struct clk_hw *hw = __clk_get_hw(clk); + struct ccu_common *cm = hw_to_ccu_common(hw); + unsigned long flags; + u32 val; + + if (!(cm->features & CCU_FEATURE_MMC_TIMING_SWITCH)) + return -ENOTSUPP; + + spin_lock_irqsave(cm->lock, flags); + + val = readl(cm->base + cm->reg); + if (new_mode) + val |= CCU_MMC_NEW_TIMING_MODE; + else + val &= ~CCU_MMC_NEW_TIMING_MODE; + writel(val, cm->base + cm->reg); + + spin_unlock_irqrestore(cm->lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(sunxi_ccu_set_mmc_timing_mode); + +/** + * sunxi_ccu_set_mmc_timing_mode: Get the current MMC clock timing mode + * @clk: clock to query + * + * Returns 0 if the clock is in old timing mode, > 0 if it is in + * new timing mode, and -ENOTSUPP if the clock does not support + * this function. + */ +int sunxi_ccu_get_mmc_timing_mode(struct clk *clk) +{ + struct clk_hw *hw = __clk_get_hw(clk); + struct ccu_common *cm = hw_to_ccu_common(hw); + + if (cm->features & CCU_FEATURE_MMC_ALWAYS_NEW) + return 1; + + if (!(cm->features & CCU_FEATURE_MMC_TIMING_SWITCH)) + return -ENOTSUPP; + + return !!(readl(cm->base + cm->reg) & CCU_MMC_NEW_TIMING_MODE); +} +EXPORT_SYMBOL_GPL(sunxi_ccu_get_mmc_timing_mode); diff --git a/include/l
Re: [PATCH RFC v5] cpufreq: schedutil: Make iowait boost more energy efficient
On 19-07-17, 19:38, Joel Fernandes wrote: > On Tue, Jul 18, 2017 at 11:19 PM, Viresh Kumar > wrote: > > On 18-07-17, 21:39, Joel Fernandes wrote: > >> Not really, to me B will still work because in the case the flag is > >> set, we are correctly double boosting in the next cycle. > >> > >> Taking an example, with B = flag is set and D = flag is not set > >> > >> F = Fmin (minimum) > >> > >> iowait flag B BBDDD > >> resulting boost F 2*F 4*F 4*F 2*F F > > > > What about this ? > > > > iowait flag B DBDBD > > resulting boost F 2*F F2*F F2*F > > Yes I guess so but this oscillation can still happen in current code I think. How ? > > diff --git a/kernel/sched/cpufreq_schedutil.c > > b/kernel/sched/cpufreq_schedutil.c > > index 45fcf21ad685..ceac5f72d8da 100644 > > --- a/kernel/sched/cpufreq_schedutil.c > > +++ b/kernel/sched/cpufreq_schedutil.c > > @@ -53,6 +53,7 @@ struct sugov_cpu { > > struct update_util_data update_util; > > struct sugov_policy *sg_policy; > > > > + bool iowait_boost_pending; > > unsigned long iowait_boost; > > unsigned long iowait_boost_max; > > u64 last_update; > > @@ -169,7 +170,17 @@ static void sugov_set_iowait_boost(struct sugov_cpu > > *sg_cpu, u64 time, > >unsigned int flags) > > { > > if (flags & SCHED_CPUFREQ_IOWAIT) { > > - sg_cpu->iowait_boost = sg_cpu->iowait_boost_max; > > + if (sg_cpu->iowait_boost_pending) > > + return; > > + > > + sg_cpu->iowait_boost_pending = true; > > + > > + if (sg_cpu->iowait_boost) { > > + sg_cpu->iowait_boost = min(sg_cpu->iowait_boost << > > 1, > > + > > sg_cpu->iowait_boost_max); > > + } else { > > + sg_cpu->iowait_boost = > > sg_cpu->sg_policy->policy->min; > > + } > > I would prefer this to be: > > if (sg_cpu->iowait_boost >= policy->min) { > // double it > } else { > // set it to min > } > > This is for the case when boost happens all the way, then its capped > at max, but when its decayed back, its not exactly decayed to Fmin but > lower than it, so in that case when boost next time we start from > Fmin. Actually you can add another patch first which makes iowait_boost as 0 when it goes below min as that problem exists today as well. And this patch would be fine then as is ? > > } else if (sg_cpu->iowait_boost) { > > s64 delta_ns = time - sg_cpu->last_update; > > > > @@ -182,17 +193,23 @@ static void sugov_set_iowait_boost(struct sugov_cpu > > *sg_cpu, u64 time, > > static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, unsigned long > > *util, > >unsigned long *max) > > { > > - unsigned long boost_util = sg_cpu->iowait_boost; > > - unsigned long boost_max = sg_cpu->iowait_boost_max; > > + unsigned long boost_util, boost_max; > > > > - if (!boost_util) > > + if (!sg_cpu->iowait_boost) > > return; > > > > + if (sg_cpu->iowait_boost_pending) > > + sg_cpu->iowait_boost_pending = false; > > + else > > + sg_cpu->iowait_boost >>= 1; > > + > > + boost_util = sg_cpu->iowait_boost; > > + boost_max = sg_cpu->iowait_boost_max; > > + > > if (*util * boost_max < *max * boost_util) { > > *util = boost_util; > > *max = boost_max; > > This looks good to me and is kind of what I had in mind. I can spend > some time testing it soon. Just to be clear if I were to repost this > patch after testing, should I have your authorship and my tested-by or > do you prefer something else? You can keep your authorship I wouldn't mind. Maybe a suggested-by at max would be fine. -- viresh
Re: [PATCH] powerpc: Convert to using %pOF instead of full_name
Rob Herring writes: > On Wed, Jul 19, 2017 at 7:03 AM, Michael Ellerman wrote: >> Rob Herring writes: >> >>> Now that we have a custom printf format specifier, convert users of >>> full_name to use %pOF instead. This is preparation to remove storing >>> of the full path string for each node. >>> >>> Signed-off-by: Rob Herring >>> Cc: Benjamin Herrenschmidt >>> Cc: Paul Mackerras >>> Cc: Michael Ellerman >>> Cc: Anatolij Gustschin >>> Cc: Scott Wood >>> Cc: Kumar Gala >>> Cc: Arnd Bergmann >>> Cc: linuxppc-...@lists.ozlabs.org >>> --- >> ... >>> 79 files changed, 464 insertions(+), 490 deletions(-) >> >> Is the plan that I'll merge this for 4.14 ? > > Yes, hence why it's not a series and sent to you. OK thanks. That was a bit too subtle for me :) cheers
Re: perf: bisected sampling bug in Linux 4.11-rc1
On Tue, 18 Jul 2017, Ingo Molnar wrote: > > Ok, great - if this works then I'll pick up this fix instead of the revert > that > I've queued up earlier today. sorry for the delay, I was out of town for a few days. I've tried the patch and it looks like it fixes the test in question and doesn't seem to add any other regressions. Vince
linux-next: build failure after merge of the userns tree
Hi Eric, After merging the userns tree, today's linux-next build (powerpc ppc64_defconfig) failed like this: kernel/pid_namespace.c: In function 'create_pid_namespace': kernel/pid_namespace.c:105:7: error: too many arguments to function 'in_userns' if (!in_userns(parent_pid_ns->user_ns, user_ns)) ^ In file included from kernel/pid_namespace.c:13:0: include/linux/user_namespace.h:148:20: note: declared here static inline bool in_userns(const struct user_namespace *target_ns) ^ Caused by commit 1f1b28d80cd9 ("userns,pidns: Verify the userns for new pid namespaces") I have used the userns tree from next-20170719 for today. -- Cheers, Stephen Rothwell
Re: [PATCH] watchdog: imx2_wdt: use new_timeout value to override the old
On 2017年07月20日 11:18, Guenter Roeck wrote: On 07/19/2017 07:45 PM, yanjiang@windriver.com wrote: From: Yanjiang Jin Without this patch we couldn't change the timeout value of imx2_wdt. Signed-off-by: Yanjiang Jin --- drivers/watchdog/imx2_wdt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index 4874b0f..6cfeee6 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -178,6 +178,9 @@ static int imx2_wdt_set_timeout(struct watchdog_device *wdog, regmap_update_bits(wdev->regmap, IMX2_WDT_WCR, IMX2_WDT_WCR_WT, WDOG_SEC_TO_COUNT(new_timeout)); + +wdog->timeout = new_timeout; + I must be missing something. That very same code is already in line 177, added with commit 30dd4a8f08b57 ("watchdog: imx2_wdt: also set wdog->timeout to new_timeout") back in 2015. Did you see this in an older kernel, maybe ? Oh, I missed this. I did use the older kernel to validate it. Thanks for your reminder, please ignore my patch. Thanks again! Regards! Yanjiang Guenter
Re: [PATCH v2 5/7] Input: gpio_keys - use devm_device_add_group() for attributes
On 07/19/2017 05:24 PM, Dmitry Torokhov wrote: Now that we have proper managed API to create device attributes, let's start using it instead of the manual unwinding. Signed-off-by: Dmitry Torokhov Reviewed-by: Guenter Roeck --- drivers/input/keyboard/gpio_keys.c | 16 ++-- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index f52812db91bc..e9f0ebf3267a 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -827,7 +827,7 @@ static int gpio_keys_probe(struct platform_device *pdev) fwnode_handle_put(child); - error = sysfs_create_group(&dev->kobj, &gpio_keys_attr_group); + error = devm_device_add_group(dev, &gpio_keys_attr_group); if (error) { dev_err(dev, "Unable to export keys/switches, error: %d\n", error); @@ -838,22 +838,11 @@ static int gpio_keys_probe(struct platform_device *pdev) if (error) { dev_err(dev, "Unable to register input device, error: %d\n", error); - goto err_remove_group; + return error; } device_init_wakeup(dev, wakeup); - return 0; - -err_remove_group: - sysfs_remove_group(&dev->kobj, &gpio_keys_attr_group); - return error; -} - -static int gpio_keys_remove(struct platform_device *pdev) -{ - sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); - return 0; } @@ -912,7 +901,6 @@ static SIMPLE_DEV_PM_OPS(gpio_keys_pm_ops, gpio_keys_suspend, gpio_keys_resume); static struct platform_driver gpio_keys_device_driver = { .probe = gpio_keys_probe, - .remove = gpio_keys_remove, .driver = { .name = "gpio-keys", .pm = &gpio_keys_pm_ops,
Re: [PATCH v2 6/7] Input: synaptics_rmi4 - use devm_device_add_group() for attributes in F01
On 07/19/2017 05:24 PM, Dmitry Torokhov wrote: Now that we have proper managed API to create device attributes, let's start using it instead of the manual unwinding. Signed-off-by: Dmitry Torokhov Reviewed-by: Guenter Roeck --- drivers/input/rmi4/rmi_f01.c | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c index aa1aabfdbe7c..ae966e333a2f 100644 --- a/drivers/input/rmi4/rmi_f01.c +++ b/drivers/input/rmi4/rmi_f01.c @@ -570,18 +570,14 @@ static int rmi_f01_probe(struct rmi_function *fn) dev_set_drvdata(&fn->dev, f01); - error = sysfs_create_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group); + error = devm_device_add_group(&fn->rmi_dev->dev, &rmi_f01_attr_group); if (error) - dev_warn(&fn->dev, "Failed to create sysfs group: %d\n", error); + dev_warn(&fn->dev, +"Failed to create attribute group: %d\n", error); return 0; } -static void rmi_f01_remove(struct rmi_function *fn) -{ - sysfs_remove_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group); -} - static int rmi_f01_config(struct rmi_function *fn) { struct f01_data *f01 = dev_get_drvdata(&fn->dev); @@ -721,7 +717,6 @@ struct rmi_function_handler rmi_f01_handler = { }, .func = 0x01, .probe = rmi_f01_probe, - .remove = rmi_f01_remove, .config = rmi_f01_config, .attention = rmi_f01_attention, .suspend= rmi_f01_suspend,
Re: [PATCH v2 7/7] Input: axp20x-pek - switch to using devm_device_add_group()
On 07/19/2017 05:24 PM, Dmitry Torokhov wrote: Now that we have proper managed API to create device attributes, let's use it instead of installing a custom devm action. Signed-off-by: Dmitry Torokhov Reviewed-by: Guenter Roeck --- drivers/input/misc/axp20x-pek.c | 18 +- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c index 38c79ebff033..cfeb0e943de6 100644 --- a/drivers/input/misc/axp20x-pek.c +++ b/drivers/input/misc/axp20x-pek.c @@ -182,13 +182,6 @@ static irqreturn_t axp20x_pek_irq(int irq, void *pwr) return IRQ_HANDLED; } -static void axp20x_remove_sysfs_group(void *_data) -{ - struct device *dev = _data; - - sysfs_remove_group(&dev->kobj, &axp20x_attribute_group); -} - static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek, struct platform_device *pdev) { @@ -313,22 +306,13 @@ static int axp20x_pek_probe(struct platform_device *pdev) return error; } - error = sysfs_create_group(&pdev->dev.kobj, &axp20x_attribute_group); + error = devm_device_add_group(&pdev->dev, &axp20x_attribute_group); if (error) { dev_err(&pdev->dev, "Failed to create sysfs attributes: %d\n", error); return error; } - error = devm_add_action(&pdev->dev, - axp20x_remove_sysfs_group, &pdev->dev); - if (error) { - axp20x_remove_sysfs_group(&pdev->dev); - dev_err(&pdev->dev, "Failed to add sysfs cleanup action: %d\n", - error); - return error; - } - platform_set_drvdata(pdev, axp20x_pek); return 0;
[GIT PULL] f2fs: update for 4.13-rc2
Hi Linus, Could you please pull this request? Thanks, The following changes since commit 5771a8c08880cdca3bfb4a3fc6d309d6bba20877: Linux v4.13-rc1 (2017-07-15 15:22:10 -0700) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git tags/for-f2fs-v4.13-rc2 for you to fetch changes up to 4db08d016ccedb5b97869724a096990acad59685: f2fs: avoid cpu lockup (2017-07-17 19:23:18 -0700) for-f2fs-v4.13-rc2 We've filed some bug fixes: - missing f2fs case in terms of stale SGID big, introduced by Jan - build error for seq_file.h - avoid cpu lockup - wrong inode_unlock in error case Jaegeuk Kim (3): f2fs: Don't clear SGID when inheriting ACLs f2fs: include seq_file.h for sysfs.c f2fs: avoid cpu lockup Luis Henriques (1): f2fs: remove extra inode_unlock() in error path fs/f2fs/acl.c| 2 +- fs/f2fs/checkpoint.c | 10 ++ fs/f2fs/file.c | 5 + fs/f2fs/sysfs.c | 1 + 4 files changed, 13 insertions(+), 5 deletions(-)
Re: [PATCH] watchdog: imx2_wdt: use new_timeout value to override the old
On 07/19/2017 07:45 PM, yanjiang@windriver.com wrote: From: Yanjiang Jin Without this patch we couldn't change the timeout value of imx2_wdt. Signed-off-by: Yanjiang Jin --- drivers/watchdog/imx2_wdt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index 4874b0f..6cfeee6 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -178,6 +178,9 @@ static int imx2_wdt_set_timeout(struct watchdog_device *wdog, regmap_update_bits(wdev->regmap, IMX2_WDT_WCR, IMX2_WDT_WCR_WT, WDOG_SEC_TO_COUNT(new_timeout)); + + wdog->timeout = new_timeout; + I must be missing something. That very same code is already in line 177, added with commit 30dd4a8f08b57 ("watchdog: imx2_wdt: also set wdog->timeout to new_timeout") back in 2015. Did you see this in an older kernel, maybe ? Guenter
Re: [PATCH RESEND v4] MAINTAINERS: fix lots of alphabetic ordering
On Wed, 2017-07-19 at 18:05 -0700, Joe Perches wrote: > On Wed, 2017-07-19 at 17:08 -0700, Linus Torvalds wrote: > > (b) we could split this thing up some sane way. > > > > Anybody got any ideas? [] > Just for ease of manipulation and not breaking the script much, > I'd suggest just having a MAINTAINERS directory and stuffing > each of the sections into separate files. > > The script would only need to add $ cat MAINTAINERS/* as input. Maybe something like the script below to break up the MAINTAINERS file into separate files. It also uses underscores for spaces in the section header -> filename translation. This seems to work OK except for this single section which doesn't follow the normal single line section header style. EDAC-XGENE APPLIED MICRO (APM) X-GENE SOC EDAC M: Loc Ho S: Supported F: drivers/edac/xgene_edac.c F: Documentation/devicetree/bindings/edac/apm-xgene-edac.txt That one would need manual fixup. --- $ cat separate_MAINTAINERS.bash mkdir MAINTAINERS.tmp sed -n '3,122p' MAINTAINERS > MAINTAINERS.tmp/00-README sed -n '131,50p' MAINTAINERS | while read line; do if [[ ! "$line" =~ ^[A-Z0-9a-z][A-Z0-9a-z\.\-] ]]; then echo "bad line: $line" continue fi file=MAINTAINERS.tmp/$(echo -n $line | sed -r -e 's/\s+/_/g' -e 's@/@-@g' -e 's/_-_/-/' -e 's/:*$//') echo "$line" > $file while read line; do if [[ ! $line =~ ^[A-Z]: ]]; then break fi echo "$line" >> $file done done $
Re: [PATCH 0/2] fixed ethernet binding violation for reset signal
Hi, Matthias just a gentle ping on this Sean On Wed, 2017-06-21 at 15:49 +0800, sean.w...@mediatek.com wrote: > From: Sean Wang > > Fixed binding violation and also updated related binding documentation to > reflect the reset signals the MediaTek Ethernet requires. > > Sean Wang (2): > dt-bindings: net: mediatek: update documentation for reset signals > arm: dts: mt7623: fixup binding violation missing reset in ethernet > node > > Documentation/devicetree/bindings/net/mediatek-net.txt | 6 -- > arch/arm/boot/dts/mt7623.dtsi | 4 > 2 files changed, 8 insertions(+), 2 deletions(-) >
Re: [PATCH v5 0/2] Add Basic SoC support for MT7622
Hi, Matthias just a gentle ping on this Sean On Sat, 2017-06-17 at 01:06 +0800, sean.w...@mediatek.com wrote: > From: Sean Wang > > Changes since v4: > - redefine the two dummy clocks with the correct frequency > which is 25MHz and 280MHz respectively. > > Changes since v3: > - get rid of those accepted patches > - rebased to branch v4.12-next/dts64 in Matthias' tree > - fixed uart node in dts with two clocks as described in bindings > documentation > > Changes since v2: > - merge back required basic clock nodes into the .dtsi file > - update the property of interrupts in timer nodes with 2 CPUs > > Changes since v1: > - update SPDX-License-Identifier > - remove next-level-cache property since cache geometry detection was removed > since 4.12 > > This patch set adds basic SoC support for MediaTek MT7622 > SoC based on 4.12-rc1. > > Sean Wang (2): > arm64: dts: mt7622: add basic nodes to the mt7622.dtsi file > arm64: dts: mt7622: add dts file for MT7622 reference board variant 1 > > arch/arm64/boot/dts/mediatek/Makefile| 1 + > arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 27 +++ > arch/arm64/boot/dts/mediatek/mt7622.dtsi | 110 > +++ > 3 files changed, 138 insertions(+) > create mode 100644 arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts > create mode 100644 arch/arm64/boot/dts/mediatek/mt7622.dtsi >
Re: [PATCH 4/4] iommu/iova: Make dma_32bit_pfn implicit
On 2017/7/19 23:07, kbuild test robot wrote: > Hi Zhen, > > [auto build test WARNING on iommu/next] > [also build test WARNING on v4.13-rc1] > [if your patch is applied to the wrong git tree, please drop us a note to > help improve the system] > > url: > https://github.com/0day-ci/linux/commits/Robin-Murphy/Optimise-64-bit-IOVA-allocations/20170719-060847 > base: https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next > config: arm-multi_v7_defconfig (attached as .config) > compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705 > reproduce: > wget > https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O > ~/bin/make.cross > chmod +x ~/bin/make.cross > # save the attached .config to linux build tree > make.cross ARCH=arm > > All warnings (new ones prefixed by >>): > >drivers/iommu/iova.c: In function 'init_iova_domain': >>> drivers/iommu/iova.c:53:41: warning: large integer implicitly truncated to >>> unsigned type [-Woverflow] > iovad->dma_32bit_pfn = iova_pfn(iovad, 1ULL << 32); OK, I see. I think the problem is that "1ULL << 32" exceed the scope of 32bits general register. We should replace "1ULL << 32" with DMA_BIT_MASK(32), the latter will minus one to keep it can be safely stored in the general register. iovad->dma_32bit_pfn = iova_pfn(iovad, DMA_BIT_MASK(32)) + 1; > ^~~~ > > vim +53 drivers/iommu/iova.c > > 35 > 36void > 37init_iova_domain(struct iova_domain *iovad, unsigned long > granule, > 38unsigned long start_pfn) > 39{ > 40/* > 41 * IOVA granularity will normally be equal to the > smallest > 42 * supported IOMMU page size; both *must* be capable of > 43 * representing individual CPU pages exactly. > 44 */ > 45BUG_ON((granule > PAGE_SIZE) || > !is_power_of_2(granule)); > 46 > 47spin_lock_init(&iovad->iova_rbtree_lock); > 48iovad->rbroot = RB_ROOT; > 49iovad->cached_node = NULL; > 50iovad->cached32_node = NULL; > 51iovad->granule = granule; > 52iovad->start_pfn = start_pfn; > > 53iovad->dma_32bit_pfn = iova_pfn(iovad, 1ULL << 32); > 54init_iova_rcaches(iovad); > 55} > 56EXPORT_SYMBOL_GPL(init_iova_domain); > 57 > > --- > 0-DAY kernel test infrastructureOpen Source Technology Center > https://lists.01.org/pipermail/kbuild-all Intel Corporation > -- Thanks! BestRegards
Re: [PATCH v9 05/10] mm: thp: enable thp migration in generic path
On 19 Jul 2017, at 16:59, Andrew Morton wrote: On Wed, 19 Jul 2017 14:39:43 -0400 "Zi Yan" wrote: On 19 Jul 2017, at 4:04, kbuild test robot wrote: Hi Zi, [auto build test WARNING on mmotm/master] [also build test WARNING on v4.13-rc1 next-20170718] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2F0day-ci%2Flinux%2Fcommits%2FZi-Yan%2Fmm-page-migration-enhancement-for-thp%2F20170718-095519&data=02%7C01%7Czi.yan%40cs.rutgers.edu%7Ca711ac47d4c0436ef66f08d4ce7cf30c%7Cb92d2b234d35447093ff69aca6632ffe%7C1%7C0%7C636360483431631457&sdata=NpxRpWbxe6o56xDJYpw1K6wgQo11IPCAbG2tE8l%2BU6E%3D&reserved=0 base: git://git.cmpxchg.org/linux-mmotm.git master config: xtensa-common_defconfig (attached as .config) compiler: xtensa-linux-gcc (GCC) 4.9.0 reproduce: wget https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fraw.githubusercontent.com%2F01org%2Flkp-tests%2Fmaster%2Fsbin%2Fmake.cross&data=02%7C01%7Czi.yan%40cs.rutgers.edu%7Ca711ac47d4c0436ef66f08d4ce7cf30c%7Cb92d2b234d35447093ff69aca6632ffe%7C1%7C0%7C636360483431631457&sdata=rBCfu0xUg3v%2B8r%2Be2tsiqRcqw%2FEZSTa4OtF0hU%2FqMbc%3D&reserved=0 -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=xtensa All warnings (new ones prefixed by >>): In file included from mm/vmscan.c:55:0: include/linux/swapops.h: In function 'swp_entry_to_pmd': include/linux/swapops.h:220:2: warning: missing braces around initializer [-Wmissing-braces] return (pmd_t){ 0 }; ^ include/linux/swapops.h:220:2: warning: (near initialization for '(anonymous).pud') [-Wmissing-braces] vim +220 include/linux/swapops.h 217 218 static inline pmd_t swp_entry_to_pmd(swp_entry_t entry) 219 { 220 return (pmd_t){ 0 }; 221 } 222 It is a GCC 4.9.0 bug: https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgcc.gnu.org%2Fbugzilla%2Fshow_bug.cgi%3Fid%3D53119&data=02%7C01%7Czi.yan%40cs.rutgers.edu%7C07c903c4f1444958942508d4cee90ca7%7Cb92d2b234d35447093ff69aca6632ffe%7C1%7C0%7C636360947714283172&sdata=84%2BXG7hglTCsTjGA8G3jyL7%2BFupkQaMkjAwzofffA5A%3D&reserved=0 Upgrading GCC can get rid of this warning. I think there was a workaround for this, but I don't recall what it was. This suppressed the warning: --- a/include/linux/swapops.h~a +++ a/include/linux/swapops.h @@ -217,7 +217,7 @@ static inline swp_entry_t pmd_to_swp_ent static inline pmd_t swp_entry_to_pmd(swp_entry_t entry) { - return (pmd_t){ 0 }; + return (pmd_t){}; } static inline int is_pmd_migration_entry(pmd_t pmd) But I don't know if this is the approved workaround and I don't know what it will do at runtime! But we should fix this. Expecting zillions of people to update their compiler version isn't nice. How about this one? --- a/include/linux/swapops.h +++ b/include/linux/swapops.h @@ -219,7 +219,7 @@ static inline swp_entry_t pmd_to_swp_entry(pmd_t pmd) static inline pmd_t swp_entry_to_pmd(swp_entry_t entry) { - return (pmd_t){ 0 }; + return __pmd(0); } static inline int is_pmd_migration_entry(pmd_t pmd) No warning or error was present during i386 kernel compilations with gcc-4.9.3 or gcc-6.4.0. i386 gcc should share the same front-end as xtensa-linux-gcc. __pmd() should be the standard way of making pmd entries, right? -- Best Regards Yan Zi
[PATCH] watchdog: imx2_wdt: use new_timeout value to override the old
From: Yanjiang Jin Without this patch we couldn't change the timeout value of imx2_wdt. Signed-off-by: Yanjiang Jin --- drivers/watchdog/imx2_wdt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index 4874b0f..6cfeee6 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -178,6 +178,9 @@ static int imx2_wdt_set_timeout(struct watchdog_device *wdog, regmap_update_bits(wdev->regmap, IMX2_WDT_WCR, IMX2_WDT_WCR_WT, WDOG_SEC_TO_COUNT(new_timeout)); + + wdog->timeout = new_timeout; + return 0; } -- 1.9.1
[PATCH v2 2/2] misc: eeprom_93xx46: Include
From: Fabio Estevam eeprom_93xx46_platform_data struct has a 'struct gpio_desc' type member, so it is better to include , which provides 'struct gpio_desc' type. Signed-off-by: Fabio Estevam --- Changes since v1: - None include/linux/eeprom_93xx46.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/linux/eeprom_93xx46.h b/include/linux/eeprom_93xx46.h index 885f587..9158987 100644 --- a/include/linux/eeprom_93xx46.h +++ b/include/linux/eeprom_93xx46.h @@ -2,8 +2,7 @@ * Module: eeprom_93xx46 * platform description for 93xx46 EEPROMs. */ - -struct gpio_desc; +#include struct eeprom_93xx46_platform_data { unsigned char flags; -- 2.7.4
[PATCH v5 6/7] dt-bindings: display: rockchip: fill Documents for vop series
Signed-off-by: Mark Yao --- Changes in v5: - clean document commit title - move changes description out of docummit commit msg Changes in v2: - rename rk322x to rk3228 - correct some vop registers define Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt | 4 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt index 9eb3f0a..5d835d9 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt @@ -8,8 +8,12 @@ Required properties: - compatible: value should be one of the following "rockchip,rk3036-vop"; "rockchip,rk3288-vop"; + "rockchip,rk3368-vop"; + "rockchip,rk3366-vop"; "rockchip,rk3399-vop-big"; "rockchip,rk3399-vop-lit"; + "rockchip,rk3228-vop"; + "rockchip,rk3328-vop"; - interrupts: should contain a list of all VOP IP block interrupts in the order: VSYNC, LCD_SYSTEM. The interrupt specifier -- 1.9.1
[PATCH v5 4/7] drm/rockchip: vop: group vop registers
Grouping the vop registers facilitates make register definition clearer, and also is useful for different vop reuse the same group register. Signed-off-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 99 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 61 +--- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 106 +++- 3 files changed, 142 insertions(+), 124 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 4f6c7bc..92d098b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -42,27 +42,20 @@ #include "rockchip_drm_psr.h" #include "rockchip_drm_vop.h" -#define REG_SET(x, base, reg, v, mode) \ - vop_mask_write(x, base + reg.offset, reg.mask, reg.shift, \ - v, reg.write_mask, reg.relaxed) -#define REG_SET_MASK(x, base, reg, mask, v, mode) \ - vop_mask_write(x, base + reg.offset, \ - mask, reg.shift, v, reg.write_mask, reg.relaxed) - #define VOP_WIN_SET(x, win, name, v) \ - REG_SET(x, win->base, win->phy->name, v, RELAXED) + vop_reg_set(vop, &win->phy->name, win->base, ~0, v, #name) #define VOP_SCL_SET(x, win, name, v) \ - REG_SET(x, win->base, win->phy->scl->name, v, RELAXED) + vop_reg_set(vop, &win->phy->scl->name, win->base, ~0, v, #name) #define VOP_SCL_SET_EXT(x, win, name, v) \ - REG_SET(x, win->base, win->phy->scl->ext->name, v, RELAXED) -#define VOP_CTRL_SET(x, name, v) \ - REG_SET(x, 0, (x)->data->ctrl->name, v, NORMAL) + vop_reg_set(vop, &win->phy->scl->ext->name, \ + win->base, ~0, v, #name) + +#define VOP_INTR_SET_MASK(vop, name, mask, v) \ + vop_reg_set(vop, &vop->data->intr->name, 0, mask, v, #name) -#define VOP_INTR_GET(vop, name) \ - vop_read_reg(vop, 0, &vop->data->ctrl->name) +#define VOP_REG_SET(vop, group, name, v) \ + vop_reg_set(vop, &vop->data->group->name, 0, ~0, v, #name) -#define VOP_INTR_SET(vop, name, mask, v) \ - REG_SET_MASK(vop, 0, vop->data->intr->name, mask, v, NORMAL) #define VOP_INTR_SET_TYPE(vop, name, type, v) \ do { \ int i, reg = 0, mask = 0; \ @@ -72,13 +65,13 @@ mask |= 1 << i; \ } \ } \ - VOP_INTR_SET(vop, name, mask, reg); \ + VOP_INTR_SET_MASK(vop, name, mask, reg); \ } while (0) #define VOP_INTR_GET_TYPE(vop, name, type) \ vop_get_intr_type(vop, &vop->data->intr->name, type) #define VOP_WIN_GET(x, win, name) \ - vop_read_reg(x, win->base, &win->phy->name) + vop_read_reg(x, win->offset, win->phy->name) #define VOP_WIN_GET_YRGBADDR(vop, win) \ vop_readl(vop, win->base + win->phy->yrgb_mst.offset) @@ -160,14 +153,20 @@ static inline uint32_t vop_read_reg(struct vop *vop, uint32_t base, return (vop_readl(vop, base + reg->offset) >> reg->shift) & reg->mask; } -static inline void vop_mask_write(struct vop *vop, uint32_t offset, - uint32_t mask, uint32_t shift, uint32_t v, - bool write_mask, bool relaxed) +static void vop_reg_set(struct vop *vop, const struct vop_reg *reg, + uint32_t _offset, uint32_t _mask, uint32_t v, + const char *reg_name) { - if (!mask) + int offset = reg->offset + _offset; + int mask = reg->mask & _mask; + int shift = reg->shift; + + if (!reg || !reg->mask) { + dev_dbg(vop->dev, "Warning: not support %s\n", reg_name); return; + } - if (write_mask) { + if (reg->write_mask) { v = ((v << shift) & 0x) | (mask << (shift + 16)); } else { uint32_t cached_val = vop->regsbak[offset >> 2]; @@ -176,7 +175,7 @@ static inline void vop_mask_write(struct vop *vop, uint32_t offset, vop->regsbak[offset >> 2] = v; } - if (relaxed) + if (reg->relaxed) writel_relaxed(v, vop->regs + offset); else writel(v, vop->regs + offset); @@ -198,7 +197,7 @@ static inline uint32_t vop_get_intr_type(struct vop *vop, static inline void vop_cfg_done(struct vop *vop) { - VOP_CTRL_SET(vop, cfg_done, 1); + VOP_REG_SET(vop, common, cfg_done, 1); } static bool has_rb_swapped(uint32_t format) @@ -536,7 +535,7 @@ static int vop_enable(struct drm_crtc *crtc) spin_lock(&vop->reg_lock); - VOP_CTRL_SET(vop, standby, 0); + VOP_REG_SET(vop, common, standby, 1); spin_unlock(&vop->reg_lock); @@ -596,7 +595,7 @@ static void vop_crtc_disable(struct drm_
[PATCH v2 1/2] misc: eeprom_93xx46: Simplify the usage of gpiod API
From: Fabio Estevam Commit 3ca9b1ac28398c ("misc: eeprom_93xx46: Add support for a GPIO 'select' line.") introduced the optional usage of 'select-gpios' by using the gpiod API in a convoluted way. Rewrite the gpiod handling to make the code simpler. Signed-off-by: Fabio Estevam --- Changes since v1: - Properly add the 1/2 notation in this patch drivers/misc/eeprom/eeprom_93xx46.c | 24 +++- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c index 94cc035..3876696 100644 --- a/drivers/misc/eeprom/eeprom_93xx46.c +++ b/drivers/misc/eeprom/eeprom_93xx46.c @@ -377,8 +377,6 @@ static int eeprom_93xx46_probe_dt(struct spi_device *spi) struct device_node *np = spi->dev.of_node; struct eeprom_93xx46_platform_data *pd; u32 tmp; - int gpio; - enum of_gpio_flags of_flags; int ret; pd = devm_kzalloc(&spi->dev, sizeof(*pd), GFP_KERNEL); @@ -403,22 +401,14 @@ static int eeprom_93xx46_probe_dt(struct spi_device *spi) if (of_property_read_bool(np, "read-only")) pd->flags |= EE_READONLY; - gpio = of_get_named_gpio_flags(np, "select-gpios", 0, &of_flags); - if (gpio_is_valid(gpio)) { - unsigned long flags = - of_flags == OF_GPIO_ACTIVE_LOW ? GPIOF_ACTIVE_LOW : 0; + pd->select = devm_gpiod_get_optional(&spi->dev, "select", +GPIOD_OUT_LOW); + if (IS_ERR(pd->select)) + return PTR_ERR(pd->select); - ret = devm_gpio_request_one(&spi->dev, gpio, flags, - "eeprom_93xx46_select"); - if (ret) - return ret; - - pd->select = gpio_to_desc(gpio); - pd->prepare = select_assert; - pd->finish = select_deassert; - - gpiod_direction_output(pd->select, 0); - } + pd->prepare = select_assert; + pd->finish = select_deassert; + gpiod_direction_output(pd->select, 0); if (of_id->data) { const struct eeprom_93xx46_devtype_data *data = of_id->data; -- 2.7.4
[PATCH v5 5/7] drm/rockchip: vop: add a series of vop support
Vop Full framework now has following vops: IP versionchipname 3.1 rk3288 3.2 rk3368 3.4 rk3366 3.5 rk3399 big 3.6 rk3399 lit 3.7 rk3228 3.8 rk3328 The above IP version is from H/W define, some of vop support get the IP version from VERSION_INFO register, some are not. hardcode the IP version for each vop to identify them. major version: used for IP structure, Vop full framework is 3, vop little framework is 2. minor version: on same structure, newer design vop will bigger then old one. Changes in v3: - fixup some mistake - use separate structures instead VOP_REG_VER mechanism Changes in v2: - rename rk322x to rk3228(Heiko Stübner) - correct some vop registers define Signed-off-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 9 + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 202 ++- drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 905 ++-- 3 files changed, 902 insertions(+), 214 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index 3ba962c..43d08c8 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -15,6 +15,14 @@ #ifndef _ROCKCHIP_DRM_VOP_H #define _ROCKCHIP_DRM_VOP_H +/* + * major: IP major version, used for IP structure + * minor: big feature change under same structure + */ +#define VOP_VERSION(major, minor) ((major) << 8 | (minor)) +#define VOP_MAJOR(version) ((version) >> 8) +#define VOP_MINOR(version) ((version) & 0xff) + enum vop_data_format { VOP_FMT_ARGB = 0, VOP_FMT_RGB888, @@ -142,6 +150,7 @@ struct vop_win_data { }; struct vop_data { + uint32_t version; const struct vop_intr *intr; const struct vop_common *common; const struct vop_misc *misc; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 53bcdd5..99f8ba4 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -276,6 +276,7 @@ }; static const struct vop_data rk3288_vop = { + .version = VOP_VERSION(3, 1), .feature = VOP_FEATURE_OUTPUT_RGB10, .intr = &rk3288_vop_intr, .common = &rk3288_common, @@ -285,7 +286,7 @@ .win_size = ARRAY_SIZE(rk3288_vop_win_data), }; -static const int rk3399_vop_intrs[] = { +static const int rk3368_vop_intrs[] = { FS_INTR, 0, 0, LINE_FLAG_INTR, @@ -295,14 +296,87 @@ DSP_HOLD_VALID_INTR, }; -static const struct vop_intr rk3399_vop_intr = { - .intrs = rk3399_vop_intrs, - .nintrs = ARRAY_SIZE(rk3399_vop_intrs), - .line_flag_num[0] = VOP_REG(RK3399_LINE_FLAG, 0x, 0), - .line_flag_num[1] = VOP_REG(RK3399_LINE_FLAG, 0x, 16), - .status = VOP_REG_MASK_SYNC(RK3399_INTR_STATUS0, 0x, 0), - .enable = VOP_REG_MASK_SYNC(RK3399_INTR_EN0, 0x, 0), - .clear = VOP_REG_MASK_SYNC(RK3399_INTR_CLEAR0, 0x, 0), +static const struct vop_intr rk3368_vop_intr = { + .intrs = rk3368_vop_intrs, + .nintrs = ARRAY_SIZE(rk3368_vop_intrs), + .line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0x, 0), + .line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0x, 16), + .status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0), + .enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0), + .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0), +}; + +static const struct vop_win_phy rk3368_win23_data = { + .data_formats = formats_win_lite, + .nformats = ARRAY_SIZE(formats_win_lite), + .gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0), + .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4), + .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5), + .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20), + .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0), + .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0), + .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0x, 0), + .yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0), + .src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0), + .dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0), +}; + +static const struct vop_win_data rk3368_vop_win_data[] = { + { .base = 0x00, .phy = &rk3288_win01_data, + .type = DRM_PLANE_TYPE_PRIMARY }, + { .base = 0x40, .phy = &rk3288_win01_data, + .type = DRM_PLANE_TYPE_OVERLAY }, + { .base = 0x00, .phy = &rk3368_win23_data, + .type = DRM_PLANE_TYPE_OVERLAY }, + { .base = 0x50, .phy = &rk3368_win23_data, + .type = DRM_PLANE_TYPE_CURSOR }, +}; + +static const struct vop_output rk3368_output = { + .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16), + .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1,
[PATCH v5 2/7] drm/rockchip: vop: move write_relaxed flags to vop register
Since the drm atomic framework, only a small part of the vop register needs sync write, Currently seems only following registers need sync write: cfg_done, standby and interrupt related register. All ctrl registers are using the sync write method that is inefficient, hardcode the write_relaxed flags to vop registers, then can only do synchronize write for those actual needed register. Signed-off-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 14 +++--- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 42 - 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 81164d6..784a2b7 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -42,18 +42,12 @@ #include "rockchip_drm_psr.h" #include "rockchip_drm_vop.h" -#define __REG_SET_RELAXED(x, off, mask, shift, v, write_mask) \ - vop_mask_write(x, off, mask, shift, v, write_mask, true) - -#define __REG_SET_NORMAL(x, off, mask, shift, v, write_mask) \ - vop_mask_write(x, off, mask, shift, v, write_mask, false) - #define REG_SET(x, base, reg, v, mode) \ - __REG_SET_##mode(x, base + reg.offset, \ -reg.mask, reg.shift, v, reg.write_mask) + vop_mask_write(x, base + reg.offset, reg.mask, reg.shift, \ + v, reg.write_mask, reg.relaxed) #define REG_SET_MASK(x, base, reg, mask, v, mode) \ - __REG_SET_##mode(x, base + reg.offset, \ -mask, reg.shift, v, reg.write_mask) + vop_mask_write(x, base + reg.offset, \ + mask, reg.shift, v, reg.write_mask, reg.relaxed) #define VOP_WIN_SET(x, win, name, v) \ REG_SET(x, win->base, win->phy->name, v, RELAXED) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 00e9d79..691dd42 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -20,17 +20,23 @@ #include "rockchip_drm_vop.h" #include "rockchip_vop_reg.h" -#define VOP_REG(off, _mask, s) \ - {.offset = off, \ +#define _VOP_REG(off, _mask, _shift, _write_mask, _relaxed) \ + { \ +.offset = off, \ .mask = _mask, \ -.shift = s, \ -.write_mask = false,} +.shift = _shift, \ +.write_mask = _write_mask, \ +.relaxed = _relaxed, \ + } -#define VOP_REG_MASK(off, _mask, s) \ - {.offset = off, \ -.mask = _mask, \ -.shift = s, \ -.write_mask = true,} +#define VOP_REG(off, _mask, _shift) \ + _VOP_REG(off, _mask, _shift, false, true) + +#define VOP_REG_SYNC(off, _mask, _shift) \ + _VOP_REG(off, _mask, _shift, false, false) + +#define VOP_REG_MASK_SYNC(off, _mask, _shift) \ + _VOP_REG(off, _mask, _shift, true, false) static const uint32_t formats_win_full[] = { DRM_FORMAT_XRGB, @@ -116,7 +122,7 @@ }; static const struct vop_ctrl rk3036_ctrl_data = { - .standby = VOP_REG(RK3036_SYS_CTRL, 0x1, 30), + .standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30), .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0), .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4), .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), @@ -124,7 +130,7 @@ .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0), .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12), - .cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0), + .cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0), }; static const struct vop_data rk3036_vop = { @@ -200,7 +206,7 @@ }; static const struct vop_ctrl rk3288_ctrl_data = { - .standby = VOP_REG(RK3288_SYS_CTRL, 0x1, 22), + .standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22), .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23), .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20), .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12), @@ -221,7 +227,7 @@ .vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0), .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12), .global_regdone_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 11), - .cfg_done = VOP_REG(RK3288_REG_CFG_DONE, 0x1, 0), + .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0), }; /* @@ -265,7 +271,7 @@ }; static const struct vop_ctrl rk3399_ctrl_data = { - .standby = VOP_REG(RK3399_SYS_CTRL, 0x1, 22), + .standby = VOP_REG_SYNC(RK3399_SYS_CTRL, 0x1, 22), .gate_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 23), .dp_en =
[PATCH v5 3/7] drm/rockchip: vop: move line_flag_num to interrupt registers
In the hardware design process, the design of line flags register is associated with the interrupt register, placing the line flags in the interrupt definition is more reasonable, and it would make multi-vop define easilier. Changes in v3: - Explain more in details, introduce why we need this patch Signed-off-by: Mark Yao Reviewed-by: Sean Paul --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 4 ++-- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 8 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 784a2b7..4f6c7bc 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -982,7 +982,7 @@ static void vop_crtc_enable(struct drm_crtc *crtc) VOP_CTRL_SET(vop, vact_st_end, val); VOP_CTRL_SET(vop, vpost_st_end, val); - VOP_CTRL_SET(vop, line_flag_num[0], vact_end); + VOP_INTR_SET(vop, line_flag_num[0], vact_end); clk_set_rate(vop->dclk, adjusted_mode->clock * 1000); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index 084d3b2..9c5da32 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -59,8 +59,6 @@ struct vop_ctrl { struct vop_reg hpost_st_end; struct vop_reg vpost_st_end; - struct vop_reg line_flag_num[2]; - struct vop_reg global_regdone_en; struct vop_reg cfg_done; }; @@ -68,6 +66,8 @@ struct vop_ctrl { struct vop_intr { const int *intrs; uint32_t nintrs; + + struct vop_reg line_flag_num[2]; struct vop_reg enable; struct vop_reg clear; struct vop_reg status; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 691dd42..064a46d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -116,6 +116,7 @@ static const struct vop_intr rk3036_intr = { .intrs = rk3036_vop_intrs, .nintrs = ARRAY_SIZE(rk3036_vop_intrs), + .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12), .status = VOP_REG(RK3036_INT_STATUS, 0xf, 0), .enable = VOP_REG(RK3036_INT_STATUS, 0xf, 4), .clear = VOP_REG(RK3036_INT_STATUS, 0xf, 8), @@ -129,7 +130,6 @@ .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0), .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0), - .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12), .cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0), }; @@ -225,7 +225,6 @@ .vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0), .hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0), .vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0), - .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12), .global_regdone_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 11), .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0), }; @@ -257,6 +256,7 @@ static const struct vop_intr rk3288_vop_intr = { .intrs = rk3288_vop_intrs, .nintrs = ARRAY_SIZE(rk3288_vop_intrs), + .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12), .status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0), .enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4), .clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8), @@ -293,8 +293,6 @@ .vact_st_end = VOP_REG(RK3399_DSP_VACT_ST_END, 0x1fff1fff, 0), .hpost_st_end = VOP_REG(RK3399_POST_DSP_HACT_INFO, 0x1fff1fff, 0), .vpost_st_end = VOP_REG(RK3399_POST_DSP_VACT_INFO, 0x1fff1fff, 0), - .line_flag_num[0] = VOP_REG(RK3399_LINE_FLAG, 0x, 0), - .line_flag_num[1] = VOP_REG(RK3399_LINE_FLAG, 0x, 16), .cfg_done = VOP_REG_MASK_SYNC(RK3399_REG_CFG_DONE, 0x1, 0), }; @@ -311,6 +309,8 @@ static const struct vop_intr rk3399_vop_intr = { .intrs = rk3399_vop_intrs, .nintrs = ARRAY_SIZE(rk3399_vop_intrs), + .line_flag_num[0] = VOP_REG(RK3399_LINE_FLAG, 0x, 0), + .line_flag_num[1] = VOP_REG(RK3399_LINE_FLAG, 0x, 16), .status = VOP_REG_MASK_SYNC(RK3399_INTR_STATUS0, 0x, 0), .enable = VOP_REG_MASK_SYNC(RK3399_INTR_EN0, 0x, 0), .clear = VOP_REG_MASK_SYNC(RK3399_INTR_CLEAR0, 0x, 0), -- 1.9.1
[PATCH v5 7/7] drm/rockchip: vop: rk3328: fix overlay abnormal
It's a hardware bug, all window's overlay channel reset value is same, hardware overlay would be die. so we must initial difference id for each overlay channel. The Channel register is supported on all vop will full design. Following is the details for this register VOP_WIN0_CTRL2 bit[7:4] win_rid_win0_cbr axi read id of win0 cbr channel bit[3:0] win_rid_win0_yrgb axi read id of win0 yrgb channel Signed-off-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 ++ drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 1 + 3 files changed, 4 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 92d098b..e4b3388 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1452,7 +1452,9 @@ static int vop_initial(struct vop *vop) for (i = 0; i < vop_data->win_size; i++) { const struct vop_win_data *win = &vop_data->win[i]; + int channel = i * 2 + 1; + VOP_WIN_SET(vop, win, channel, (channel + 1) << 4 | channel); VOP_WIN_SET(vop, win, enable, 0); VOP_WIN_SET(vop, win, gate, 1); } diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index 43d08c8..af1091f 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -141,6 +141,7 @@ struct vop_win_phy { struct vop_reg dst_alpha_ctl; struct vop_reg src_alpha_ctl; + struct vop_reg channel; }; struct vop_win_data { diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 99f8ba4..cc8d408 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -196,6 +196,7 @@ .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16), .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0), .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0), + .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0), }; static const struct vop_win_phy rk3288_win23_data = { -- 1.9.1
[PATCH v5 0/7] drm/rockchip: add all full framework vop support
These patches try to make all current rockchip full framework vop works on drm, fill missing vop on full framework. Vop Full framework now has following vops: IP versionchipname 3.1 rk3288 3.2 rk3368 3.4 rk3366 3.5 rk3399 big 3.6 rk3399 lit 3.7 rk3228 3.8 rk3328 Group the vop register, it would make register definition clearer and more easily to reuse same group register define for difference vops. Tested on rk3399 excavator board with kernel 4.13-rc1. And other chips tested on rockchip kernel 4.4: https://github.com/rockchip-linux/kernel/tree/release-4.4/drivers/gpu/drm/rockchip Changes in v5: - clean document commit title - move changes description out of docummit commit msg Changes in v4: - rebase to newest torvalds kernel, fix merge conflict Changes in v3: - group vop register instead using VOP_REG_VER mechanism - Explain more on patch commit message - move write_relaxed flags to vop registers - fix rk3328 overlay abnormal Changes in v2: - rename rk322x to rk3228 - correct some vop registers define Mark Yao (7): drm/rockchip: vop: initialize registers directly drm/rockchip: vop: move write_relaxed flags to vop register drm/rockchip: vop: move line_flag_num to interrupt registers drm/rockchip: vop: group vop registers drm/rockchip: vop: add a series of vop support dt-bindings: display: rockchip: fill Documents for vop series drm/rockchip: vop: rk3328: fix overlay abnormal .../bindings/display/rockchip/rockchip-vop.txt | 4 + drivers/gpu/drm/rockchip/rockchip_drm_vop.c| 109 ++- drivers/gpu/drm/rockchip/rockchip_drm_vop.h| 81 +- drivers/gpu/drm/rockchip/rockchip_vop_reg.c| 374 ++--- drivers/gpu/drm/rockchip/rockchip_vop_reg.h| 905 - 5 files changed, 1074 insertions(+), 399 deletions(-) -- 1.9.1
[PATCH v5 1/7] drm/rockchip: vop: initialize registers directly
At present we are using init_table to initialize some registers, but the Register init table use un-document define, it is unreadable, and sometimes we only want to update tiny bits, init table method is not friendly, it's diffcult to reuse for difference chips. To make it clean, initialize registers directly, and drops init_table mechanism out. Changes in v3: - Explain more in details Signed-off-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 6 ++-- drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 10 ++- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 43 +++-- 3 files changed, 10 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 5d45033..81164d6 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1395,7 +1395,6 @@ static void vop_destroy_crtc(struct vop *vop) static int vop_initial(struct vop *vop) { const struct vop_data *vop_data = vop->data; - const struct vop_reg_data *init_table = vop_data->init_table; struct reset_control *ahb_rst; int i, ret; @@ -1455,13 +1454,14 @@ static int vop_initial(struct vop *vop) memcpy(vop->regsbak, vop->regs, vop->len); - for (i = 0; i < vop_data->table_size; i++) - vop_writel(vop, init_table[i].offset, init_table[i].value); + VOP_CTRL_SET(vop, global_regdone_en, 1); + VOP_CTRL_SET(vop, dsp_blank, 0); for (i = 0; i < vop_data->win_size; i++) { const struct vop_win_data *win = &vop_data->win[i]; VOP_WIN_SET(vop, win, enable, 0); + VOP_WIN_SET(vop, win, gate, 1); } vop_cfg_done(vop); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index 9979fd0..084d3b2 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -24,11 +24,6 @@ enum vop_data_format { VOP_FMT_YUV444SP, }; -struct vop_reg_data { - uint32_t offset; - uint32_t value; -}; - struct vop_reg { uint32_t offset; uint32_t shift; @@ -46,6 +41,7 @@ struct vop_ctrl { struct vop_reg hdmi_en; struct vop_reg mipi_en; struct vop_reg dp_en; + struct vop_reg dsp_blank; struct vop_reg out_mode; struct vop_reg dither_down; struct vop_reg dither_up; @@ -65,6 +61,7 @@ struct vop_ctrl { struct vop_reg line_flag_num[2]; + struct vop_reg global_regdone_en; struct vop_reg cfg_done; }; @@ -115,6 +112,7 @@ struct vop_win_phy { uint32_t nformats; struct vop_reg enable; + struct vop_reg gate; struct vop_reg format; struct vop_reg rb_swap; struct vop_reg act_info; @@ -136,8 +134,6 @@ struct vop_win_data { }; struct vop_data { - const struct vop_reg_data *init_table; - unsigned int table_size; const struct vop_ctrl *ctrl; const struct vop_intr *intr; const struct vop_win_data *win; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index bafd698..00e9d79 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -127,13 +127,7 @@ .cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0), }; -static const struct vop_reg_data rk3036_vop_init_reg_table[] = { - {RK3036_DSP_CTRL1, 0x}, -}; - static const struct vop_data rk3036_vop = { - .init_table = rk3036_vop_init_reg_table, - .table_size = ARRAY_SIZE(rk3036_vop_init_reg_table), .ctrl = &rk3036_ctrl_data, .intr = &rk3036_intr, .win = rk3036_vop_win_data, @@ -193,7 +187,8 @@ static const struct vop_win_phy rk3288_win23_data = { .data_formats = formats_win_lite, .nformats = ARRAY_SIZE(formats_win_lite), - .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0), + .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4), + .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0), .format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1), .rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12), .dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0), @@ -215,6 +210,7 @@ .dither_down = VOP_REG(RK3288_DSP_CTRL1, 0xf, 1), .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6), .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19), + .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18), .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0), .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4), .htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), @@ -224,22 +220,10 @@ .hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0), .vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0), .line_flag_num[0] = VOP_REG(RK3288_IN
Re: [PATCH RFC v5] cpufreq: schedutil: Make iowait boost more energy efficient
Hi Viresh, On Tue, Jul 18, 2017 at 11:19 PM, Viresh Kumar wrote: > On 18-07-17, 21:39, Joel Fernandes wrote: >> Not really, to me B will still work because in the case the flag is >> set, we are correctly double boosting in the next cycle. >> >> Taking an example, with B = flag is set and D = flag is not set >> >> F = Fmin (minimum) >> >> iowait flag B BBDDD >> resulting boost F 2*F 4*F 4*F 2*F F > > What about this ? > > iowait flag B DBDBD > resulting boost F 2*F F2*F F2*F Yes I guess so but this oscillation can still happen in current code I think. > > Isn't this the worst behavior we may wish for ? > >> What will not work is C but as I mentioned in my last email, that >> would cause us to delay the iowait boost halving by at most 1 cycle, >> is that really an issue considering we are starting from min compared >> to max? Note that cases A. and B. are still working. >> >> Considering the following cases: >> (1) min freq is 800MHz, it takes upto 4 cycles to reach 4GHz where the >> flag is set. At this point I think its likely we will run for many >> more cycles which means keeping the boost active for 1 extra cycle >> isn't that big a deal. Even if run for just 5 cycles with boost, that >> means only the last cycle will suffer from C not decaying as soon as >> possible. Comparing that to the case where in current code we >> currently run at max from the first cycle, its not that bad. >> >> (2) we have a transient type of thing, in this case we're probably not >> reaching the full max immediately so even if we delay the decaying, >> its still not as bad as what it is currently. >> >> I think considering that the code is way cleaner than any other >> approach - its a small price to pay. Also keeping in mind that this >> patch is still an improvement over the current spike, even though as >> you said its still a bit spikey, but its still better right? >> >> Functionally the code is working and I think is also clean, but if you >> feel that its still confusing, then I'm open to rewriting it. > > I am not worried for being boosted for a bit more time, but with the > spikes even when we do not want a freq change. > >> > And so in my initial solution I reversed the order in >> > sugov_iowait_boost(). >> >> Yes, but to fix A. you had to divide by 2 in sugov_set_iowait_boost, >> and then multiply by 2 later in sugov_iowait_boost to keep the first >> boost at min. That IMO was confusing so my modified patch did it >> differently. > > Yeah, it wasn't great for sure. > > I hope the following one will work for everyone ? > > diff --git a/kernel/sched/cpufreq_schedutil.c > b/kernel/sched/cpufreq_schedutil.c > index 45fcf21ad685..ceac5f72d8da 100644 > --- a/kernel/sched/cpufreq_schedutil.c > +++ b/kernel/sched/cpufreq_schedutil.c > @@ -53,6 +53,7 @@ struct sugov_cpu { > struct update_util_data update_util; > struct sugov_policy *sg_policy; > > + bool iowait_boost_pending; > unsigned long iowait_boost; > unsigned long iowait_boost_max; > u64 last_update; > @@ -169,7 +170,17 @@ static void sugov_set_iowait_boost(struct sugov_cpu > *sg_cpu, u64 time, >unsigned int flags) > { > if (flags & SCHED_CPUFREQ_IOWAIT) { > - sg_cpu->iowait_boost = sg_cpu->iowait_boost_max; > + if (sg_cpu->iowait_boost_pending) > + return; > + > + sg_cpu->iowait_boost_pending = true; > + > + if (sg_cpu->iowait_boost) { > + sg_cpu->iowait_boost = min(sg_cpu->iowait_boost << 1, > + sg_cpu->iowait_boost_max); > + } else { > + sg_cpu->iowait_boost = sg_cpu->sg_policy->policy->min; > + } I would prefer this to be: if (sg_cpu->iowait_boost >= policy->min) { // double it } else { // set it to min } This is for the case when boost happens all the way, then its capped at max, but when its decayed back, its not exactly decayed to Fmin but lower than it, so in that case when boost next time we start from Fmin. > } else if (sg_cpu->iowait_boost) { > s64 delta_ns = time - sg_cpu->last_update; > > @@ -182,17 +193,23 @@ static void sugov_set_iowait_boost(struct sugov_cpu > *sg_cpu, u64 time, > static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, unsigned long *util, >unsigned long *max) > { > - unsigned long boost_util = sg_cpu->iowait_boost; > - unsigned long boost_max = sg_cpu->iowait_boost_max; > + unsigned long boost_util, boost_max; > > - if (!boost_util) > + if (!sg_cpu->iowait_boost) > return; > > + if (sg_cpu->iowait_boost_pending) > + sg_cpu->iowait_boost_pending = false; > + else > + sg_cpu->iowait_boost >>= 1;
[PATCH 2/2] misc: eeprom_93xx46: Include
From: Fabio Estevam eeprom_93xx46_platform_data struct has a 'struct gpio_desc' type member, so it is better to include , which provides 'struct gpio_desc' type. Signed-off-by: Fabio Estevam --- include/linux/eeprom_93xx46.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/linux/eeprom_93xx46.h b/include/linux/eeprom_93xx46.h index 885f587..9158987 100644 --- a/include/linux/eeprom_93xx46.h +++ b/include/linux/eeprom_93xx46.h @@ -2,8 +2,7 @@ * Module: eeprom_93xx46 * platform description for 93xx46 EEPROMs. */ - -struct gpio_desc; +#include struct eeprom_93xx46_platform_data { unsigned char flags; -- 2.7.4
Re: [PATCH] mm/vmalloc: add vm_struct for vm_map_ram area
On 07/19/2017 06:44 PM, Zhaoyang Huang wrote: > /proc/vmallocinfo will not show the area allocated by vm_map_ram, which > will make confusion when debug. Add vm_struct for them and show them in > proc. > > Signed-off-by: Zhaoyang Huang > --- another patch titled "vmalloc: show lazy-purged vma info in vmallocinfo" was phased-in to linux-next branch to resolve this problem. > mm/vmalloc.c | 27 ++- > 1 file changed, 26 insertions(+), 1 deletion(-) > > diff --git a/mm/vmalloc.c b/mm/vmalloc.c > index 34a1c3e..4a2e93c 100644 > --- a/mm/vmalloc.c > +++ b/mm/vmalloc.c > @@ -46,6 +46,9 @@ struct vfree_deferred { > > static void __vunmap(const void *, int); > > +static void setup_vmap_ram_vm(struct vm_struct *vm, struct vmap_area *va, > + unsigned long flags, const void *caller); > + > static void free_work(struct work_struct *w) > { > struct vfree_deferred *p = container_of(w, struct vfree_deferred, wq); > @@ -315,6 +318,7 @@ unsigned long vmalloc_to_pfn(const void *vmalloc_addr) > /*** Global kva allocator ***/ > > #define VM_VM_AREA 0x04 > +#define VM_VM_RAM0x08 > > static DEFINE_SPINLOCK(vmap_area_lock); > /* Export for kexec only */ > @@ -1141,6 +1145,7 @@ void vm_unmap_ram(const void *mem, unsigned int count) > > va = find_vmap_area(addr); > BUG_ON(!va); > + kfree(va->vm); > free_unmap_vmap_area(va); > } > EXPORT_SYMBOL(vm_unmap_ram); > @@ -1173,6 +1178,12 @@ void *vm_map_ram(struct page **pages, unsigned int > count, int node, pgprot_t pro > addr = (unsigned long)mem; > } else { > struct vmap_area *va; > + struct vm_struct *area; > + > + area = kzalloc_node(sizeof(*area), GFP_KERNEL, node); > + if (unlikely(!area)) > + return NULL; > + > va = alloc_vmap_area(size, PAGE_SIZE, > VMALLOC_START, VMALLOC_END, node, GFP_KERNEL); > if (IS_ERR(va)) > @@ -1180,6 +1191,7 @@ void *vm_map_ram(struct page **pages, unsigned int > count, int node, pgprot_t pro > > addr = va->va_start; > mem = (void *)addr; > + setup_vmap_ram_vm(area, va, 0, __builtin_return_address(0)); > } > if (vmap_page_range(addr, addr + size, prot, pages) < 0) { > vm_unmap_ram(mem, count); > @@ -1362,6 +1374,19 @@ static void setup_vmalloc_vm(struct vm_struct *vm, > struct vmap_area *va, > spin_unlock(&vmap_area_lock); > } > > +static void setup_vmap_ram_vm(struct vm_struct *vm, struct vmap_area *va, > + unsigned long flags, const void *caller) > +{ > + spin_lock(&vmap_area_lock); > + vm->flags = flags; > + vm->addr = (void *)va->va_start; > + vm->size = va->va_end - va->va_start; > + vm->caller = caller; > + va->vm = vm; > + va->flags |= VM_VM_RAM; > + spin_unlock(&vmap_area_lock); > +} > + > static void clear_vm_uninitialized_flag(struct vm_struct *vm) > { > /* > @@ -2698,7 +2723,7 @@ static int s_show(struct seq_file *m, void *p) >* s_show can encounter race with remove_vm_area, !VM_VM_AREA on >* behalf of vmap area is being tear down or vm_map_ram allocation. >*/ > - if (!(va->flags & VM_VM_AREA)) > + if (!(va->flags & (VM_VM_AREA | VM_VM_RAM))) > return 0; > > v = va->vm; >
[PATCH] misc: eeprom_93xx46: Simplify the usage of gpiod API
From: Fabio Estevam Commit 3ca9b1ac28398c ("misc: eeprom_93xx46: Add support for a GPIO 'select' line.") introduced the optional usage of 'select-gpios' by using the gpiod API in a convoluted way. Rewrite the gpiod handling to make the code simpler. Signed-off-by: Fabio Estevam --- drivers/misc/eeprom/eeprom_93xx46.c | 24 +++- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c index 94cc035..3876696 100644 --- a/drivers/misc/eeprom/eeprom_93xx46.c +++ b/drivers/misc/eeprom/eeprom_93xx46.c @@ -377,8 +377,6 @@ static int eeprom_93xx46_probe_dt(struct spi_device *spi) struct device_node *np = spi->dev.of_node; struct eeprom_93xx46_platform_data *pd; u32 tmp; - int gpio; - enum of_gpio_flags of_flags; int ret; pd = devm_kzalloc(&spi->dev, sizeof(*pd), GFP_KERNEL); @@ -403,22 +401,14 @@ static int eeprom_93xx46_probe_dt(struct spi_device *spi) if (of_property_read_bool(np, "read-only")) pd->flags |= EE_READONLY; - gpio = of_get_named_gpio_flags(np, "select-gpios", 0, &of_flags); - if (gpio_is_valid(gpio)) { - unsigned long flags = - of_flags == OF_GPIO_ACTIVE_LOW ? GPIOF_ACTIVE_LOW : 0; + pd->select = devm_gpiod_get_optional(&spi->dev, "select", +GPIOD_OUT_LOW); + if (IS_ERR(pd->select)) + return PTR_ERR(pd->select); - ret = devm_gpio_request_one(&spi->dev, gpio, flags, - "eeprom_93xx46_select"); - if (ret) - return ret; - - pd->select = gpio_to_desc(gpio); - pd->prepare = select_assert; - pd->finish = select_deassert; - - gpiod_direction_output(pd->select, 0); - } + pd->prepare = select_assert; + pd->finish = select_deassert; + gpiod_direction_output(pd->select, 0); if (of_id->data) { const struct eeprom_93xx46_devtype_data *data = of_id->data; -- 2.7.4
Re: [PATCH] KVM: nVMX: Fix exception injection
Hi Jim, 2017-07-19 2:47 GMT+08:00 Jim Mattson : > Why do we expect the VM_EXIT_INTR_INFO and EXIT_QUALIFICATION fields > of the VMCS to have the correct values for the injected exception? Good point, I think we should synthesize VM_EXIT_INTR_INFO and EXIT_QUALIFICATION manually, I will post a patch for it. Btw, how about setting EXIT_QULIFICATION to vcpu->arch.cr2 for the page fault exception and 0 for other exceptions? Regards, Wanpeng Li > > On Mon, Jun 5, 2017 at 5:19 AM, Wanpeng Li wrote: >> 2017-06-05 20:07 GMT+08:00 Paolo Bonzini : >>> >>> >>> On 03/06/2017 05:21, Wanpeng Li wrote: Commit 0b6ac343fc (KVM: nVMX: Correct handling of exception injection) mentioned that "KVM wants to inject page-faults which it got to the guest. This function assumes it is called with the exit reason in vmcs02 being a #PF exception". Commit e011c663 (KVM: nVMX: Check all exceptions for intercept during delivery to L2) allows to check all exceptions for intercept during delivery to L2. However, there is no guarantee the exit reason is exception currently, when there is an external interrupt occurred on host, maybe a time interrupt for host which should not be injected to guest, and somewhere queues an exception, then the function nested_vmx_check_exception() will be called and the vmexit emulation codes will try to emulate the "Acknowledge interrupt on exit" behavior, the warning is triggered. This patch fixes it by confirming to inject exception to the guest when the exit reason in vmcs02 is exception. >>> >>> I am confused. On one hand, the comment originally "this is the only >>> case in which KVM injects a #PF when L2 is running", but I'm not sure >>> it's true. For example, KVM could emulate a movs while running L2. If >>> the source is MMIO and the destination is a missing page, the original >>> failure could be an EPT misconfig, but the access to the destination >>> would cause a #PF in the guest (could be a nice testcase for >>> kvm-unit-tests, BTW :)). >>> >>> On the other hand, why would you reuse to_vmx(vcpu)->exit_reason in >>> nested_vmx_check_exception? Would the following fix the bug: >>> >>> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c >>> index 9b4b5d6dcd34..ca5d2b93385c 100644 >>> --- a/arch/x86/kvm/vmx.c >>> +++ b/arch/x86/kvm/vmx.c >>> @@ -2425,7 +2425,7 @@ static int nested_vmx_check_exception(struct >>> kvm_vcpu *vcpu, unsigned nr) >>> if (!(vmcs12->exception_bitmap & (1u << nr))) >>> return 0; >>> >>> - nested_vmx_vmexit(vcpu, to_vmx(vcpu)->exit_reason, >>> + nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI, >>> vmcs_read32(VM_EXIT_INTR_INFO), >>> vmcs_readl(EXIT_QUALIFICATION)); >>> return 1; >>> >> >> You are right. >> >> Regards, >> Wanpeng Li
Re: [linux-sunxi] [PATCH v4 4/5] ARM: sunxi: h3/h5: switch apb0-related clocks to r_ccu
在 2017-07-20 10:03,icen...@aosc.io 写道: 在 2017-07-20 06:59,Ondřej Jirman 写道: Hi, Icenowy Zheng píše v Út 04. 04. 2017 v 17:50 +0800: From: Icenowy Zheng Now we have driver for the PRCM CCU, switch to use it instead of old-style clock nodes for apb0-related clocks in sunxi-h3-h5.dtsi . The mux 3 of R_CCU is still the internal oscillator, which is said to be 16MHz plus minus 30%, and get a measured value of 15MHz~16MHz on my two H3 boards and one H5 board. There's issue with the new r_ccu that breaks r_i2c. (no devices can be found on the bus). Reverting this patch fixes the issue with the I2C controller. (everything else being the same) Here's the code I'm using: https://github.com/megous/linux/commits/oran ge-pi-4.12 The last commit is the revert. The issue manifests itself by non-working DVFS, because kernel lacks access to SY8106A regulator, because r_i2c doesn't work with sunxi-ng clock driver (sun8i-r). Relevant difference in registers between working/non-working state is just this (diff -u): 0x01f02400 = 0x 0x01f02404 = 0x -0x01f02408 = 0x0091 +0x01f02408 = 0x0095 DATA register inisde the I2C controller 0x01f0240c = 0x0044 0x01f02410 = 0x00f8 -0x01f02414 = 0x0059 +0x01f02414 = 0x CLOCK setup register inside the I2C controller 0x01f02418 = 0x 0x01f0241c = 0x 0x01f02420 = 0x003a It looks like the new sunxi-ng clock driver causes the I2C driver to not correctly configure the CLOCK register. I don't know why and I'm not sure how to deal with this. Any ideas what can I do next? thank you and regards, o. It seems to be a very very very weird problem -- the CPUS_CFG register seems to be not accessible in non-secure mode on H3, and if the r_ccu driver reads it a value of 0x0 is read out (which means that the parent of ar100 is osc32k), but the real initial value of the register is 0x0001 (which means the parent is osc24M). So the bus clock of r_i2c is wrongly claimed as 32kHz, not 24MHz, then the r_i2c fails to work. This clock problem doesn't exist for A64. H5 doesn't have this issue either. Signed-off-by: Icenowy Zheng --- Changes in v4: - Temporarily dropped the CCU headers. Changes in v3: - Change osc32000 to iosc. arch/arm/boot/dts/sunxi-h3-h5.dtsi | 45 -- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi index 6640ebfa6419..1aeeacb3a884 100644 --- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi +++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi @@ -68,31 +68,12 @@ clock-output-names = "osc32k"; }; - apb0: apb0_clk { - compatible = "fixed-factor-clock"; + iosc: internal-osc-clk { #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - clocks = <&osc24M>; - clock-output-names = "apb0"; - }; - - apb0_gates: clk@01f01428 { - compatible = "allwinner,sun8i-h3-apb0-gates-clk", -"allwinner,sun4i-a10-gates-clk"; - reg = <0x01f01428 0x4>; - #clock-cells = <1>; - clocks = <&apb0>; - clock-indices = <0>, <1>; - clock-output-names = "apb0_pio", "apb0_ir"; - }; - - ir_clk: ir_clk@01f01454 { - compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01f01454 0x4>; - #clock-cells = <0>; - clocks = <&osc32k>, <&osc24M>; - clock-output-names = "ir"; + compatible = "fixed-clock"; + clock-frequency = <1600>; + clock-accuracy = <3>; + clock-output-names = "iosc"; }; }; @@ -576,9 +557,12 @@ ; }; - apb0_reset: reset@01f014b0 { - reg = <0x01f014b0 0x4>; - compatible = "allwinner,sun6i-a31-clock-reset"; + r_ccu: clock@1f01400 { + compatible = "allwinner,sun50i-a64-r-ccu"; + reg = <0x01f01400 0x100>; + clocks = <&osc24M>, <&osc32k>, <&iosc>; + clock-names = "hosc", "losc", "iosc"; + #clock-cells = <1>; #reset-cells = <1>; }; @@ -589,9 +573,9 @@ ir: ir@01f02000 { compatible = "allwinner,sun5i-a13-ir"; - clocks = <&apb0_gates 1>, <&ir_clk>; + clocks = <&r_ccu 4>, <&r_ccu 11>; clock-
Re: [PATCH] SCSI: remove DRIVER_ATTR() usage
On Wed, 2017-07-19 at 14:50 +0200, Greg KH wrote: > From: Greg Kroah-Hartman > > It's better to use the DRIVER_ATTR_RW() and DRIVER_ATTR_RO() macros to > explicitly show that this is a read/write or read/only sysfs file. So > convert the remaining SCSI drivers that use the old style to use the > newer macros. > > Bonus is that this removes some checkpatch.pl warnings :) Reviewed-by: Bart Van Assche
Re: [PATCH v2 5/5] dt-bindings: display: fill Documents for series of vop
On 2017年07月18日 01:24, Rob Herring wrote: On Wed, Jul 12, 2017 at 10:04:02AM +0800, Mark Yao wrote: Changes in v2: - rename rk322x to rk3228(Heiko Stübner) This goes below '---' and you need a commit msg here. Also, it is not clear in the subject this is for Rockchip. Got it, will fix it at next version. Thanks. Signed-off-by: Mark Yao --- Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt | 4 1 file changed, 4 insertions(+) ___ Linux-rockchip mailing list linux-rockc...@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-rockchip -- Mark Yao
[PATCH] remoteproc: Merge __rproc_boot() with rproc_boot()
The additional arguments in the internal __rproc_boot() function were dropped in commit 2bfc311a57f5 ("remoteproc: Drop wait in __rproc_boot()"). The exported rproc_boot() is now just a wrapper around this internal function, so merge them together. Signed-off-by: Suman Anna --- drivers/remoteproc/remoteproc_core.c | 11 +-- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 564061dcc019..6224f1036c19 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -1129,7 +1129,7 @@ static void rproc_crash_handler_work(struct work_struct *work) * * Returns 0 on success, and an appropriate error value otherwise. */ -static int __rproc_boot(struct rproc *rproc) +int rproc_boot(struct rproc *rproc) { const struct firmware *firmware_p; struct device *dev; @@ -1180,15 +1180,6 @@ static int __rproc_boot(struct rproc *rproc) mutex_unlock(&rproc->lock); return ret; } - -/** - * rproc_boot() - boot a remote processor - * @rproc: handle of a remote processor - */ -int rproc_boot(struct rproc *rproc) -{ - return __rproc_boot(rproc); -} EXPORT_SYMBOL(rproc_boot); /** -- 2.13.1
Re: [linux-sunxi] [PATCH v4 4/5] ARM: sunxi: h3/h5: switch apb0-related clocks to r_ccu
在 2017-07-20 06:59,Ondřej Jirman 写道: Hi, Icenowy Zheng píše v Út 04. 04. 2017 v 17:50 +0800: From: Icenowy Zheng Now we have driver for the PRCM CCU, switch to use it instead of old-style clock nodes for apb0-related clocks in sunxi-h3-h5.dtsi . The mux 3 of R_CCU is still the internal oscillator, which is said to be 16MHz plus minus 30%, and get a measured value of 15MHz~16MHz on my two H3 boards and one H5 board. There's issue with the new r_ccu that breaks r_i2c. (no devices can be found on the bus). Reverting this patch fixes the issue with the I2C controller. (everything else being the same) Here's the code I'm using: https://github.com/megous/linux/commits/oran ge-pi-4.12 The last commit is the revert. The issue manifests itself by non-working DVFS, because kernel lacks access to SY8106A regulator, because r_i2c doesn't work with sunxi-ng clock driver (sun8i-r). Relevant difference in registers between working/non-working state is just this (diff -u): 0x01f02400 = 0x 0x01f02404 = 0x -0x01f02408 = 0x0091 +0x01f02408 = 0x0095 DATA register inisde the I2C controller 0x01f0240c = 0x0044 0x01f02410 = 0x00f8 -0x01f02414 = 0x0059 +0x01f02414 = 0x CLOCK setup register inside the I2C controller 0x01f02418 = 0x 0x01f0241c = 0x 0x01f02420 = 0x003a It looks like the new sunxi-ng clock driver causes the I2C driver to not correctly configure the CLOCK register. I don't know why and I'm not sure how to deal with this. Any ideas what can I do next? thank you and regards, o. It seems to be a very very very weird problem -- the CPUS_CFG register seems to be not accessible in non-secure mode on H3, and if the r_ccu driver reads it a value of 0x0 is read out (which means that the parent of ar100 is osc32k), but the real initial value of the register is 0x0001 (which means the parent is osc24M). So the bus clock of r_i2c is wrongly claimed as 32kHz, not 24MHz, then the r_i2c fails to work. This clock problem doesn't exist for A64. Signed-off-by: Icenowy Zheng --- Changes in v4: - Temporarily dropped the CCU headers. Changes in v3: - Change osc32000 to iosc. arch/arm/boot/dts/sunxi-h3-h5.dtsi | 45 -- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi index 6640ebfa6419..1aeeacb3a884 100644 --- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi +++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi @@ -68,31 +68,12 @@ clock-output-names = "osc32k"; }; - apb0: apb0_clk { - compatible = "fixed-factor-clock"; + iosc: internal-osc-clk { #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - clocks = <&osc24M>; - clock-output-names = "apb0"; - }; - - apb0_gates: clk@01f01428 { - compatible = "allwinner,sun8i-h3-apb0-gates-clk", -"allwinner,sun4i-a10-gates-clk"; - reg = <0x01f01428 0x4>; - #clock-cells = <1>; - clocks = <&apb0>; - clock-indices = <0>, <1>; - clock-output-names = "apb0_pio", "apb0_ir"; - }; - - ir_clk: ir_clk@01f01454 { - compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01f01454 0x4>; - #clock-cells = <0>; - clocks = <&osc32k>, <&osc24M>; - clock-output-names = "ir"; + compatible = "fixed-clock"; + clock-frequency = <1600>; + clock-accuracy = <3>; + clock-output-names = "iosc"; }; }; @@ -576,9 +557,12 @@ ; }; - apb0_reset: reset@01f014b0 { - reg = <0x01f014b0 0x4>; - compatible = "allwinner,sun6i-a31-clock-reset"; + r_ccu: clock@1f01400 { + compatible = "allwinner,sun50i-a64-r-ccu"; + reg = <0x01f01400 0x100>; + clocks = <&osc24M>, <&osc32k>, <&iosc>; + clock-names = "hosc", "losc", "iosc"; + #clock-cells = <1>; #reset-cells = <1>; }; @@ -589,9 +573,9 @@ ir: ir@01f02000 { compatible = "allwinner,sun5i-a13-ir"; - clocks = <&apb0_gates 1>, <&ir_clk>; + clocks = <&r_ccu 4>, <&r_ccu 11>; clock-names = "apb", "ir"; - resets = <&apb0_reset 1>; +
[PATCH] rpmsg: virtio_rpmsg_bus: fix export of rpmsg_send_offchannel_raw()
Commit 8a228ecfe086b ("rpmsg: Indirection table for rpmsg_endpoint operations") has made the rpmsg_send_offchannel_raw() a static function and local to the virtio_rpmsg_bus module, but has not dropped the corresponding EXPORT_SYMBOL. Fix this. Signed-off-by: Suman Anna --- drivers/rpmsg/virtio_rpmsg_bus.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index eee2a9f77d37..7216278f2947 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -632,7 +632,6 @@ static int rpmsg_send_offchannel_raw(struct rpmsg_device *rpdev, mutex_unlock(&vrp->tx_lock); return err; } -EXPORT_SYMBOL(rpmsg_send_offchannel_raw); static int virtio_rpmsg_send(struct rpmsg_endpoint *ept, void *data, int len) { -- 2.13.1
Re: [RFC PATCH v1 00/11] Create fast idle path for short idle periods
On 2017/7/19 15:55, Thomas Gleixner wrote: > On Wed, 19 Jul 2017, Li, Aubrey wrote: >> On 2017/7/18 15:19, Thomas Gleixner wrote: >>> You can very well avoid it by taking the irq timings or whatever other >>> information into account for the NOHZ decision. >>> >> If I read the source correctly, irq timing statistics computation happens at >> idle time. Sadly, this is what Andi Kleen worried about. People keep putting >> more and more slow stuff in idle path, not realizing it could be a critical >> path. > > Can you please stop this right here? We all realize that there is an issue, > we are not as stupid as you might think. > > But we disagree that the proper solution is to add an ad hoc hack which > shortcuts stuff and creates a maintenance problem in the long run. > > Just dismissing a proposal based on 'oh this adds more code to the idle > path' and then yelling 'you all do not get it' is not going to solve this > in any way. > > You simply refuse to look at the big picture and you are just not willing > to analyze the involved bits and pieces and find a solution which allows to > serve both the NOHZ power saving and the interrupt driven workloads best. > > All you are doing is providing data about the status quo, and then > deferring from that, that you need an extra magic code path. That > information is just a inventory of the current behaviour and the current > behaviour is caused by the current implementation. There is nothing set in > stone with that implementation and it can be changed. > > But you are just in refusal mode and instead of sitting down and doing the > hard work, you accuse other people that they are not realizing the problem > and insist on your sloppy hackery. That's simply not the way it works. Don't get me wrong, even if a fast path is acceptable, we still need to figure out if the coming idle is short and when to switch. I'm just worried about if irq timings is not an ideal statistics, we have to skip it too. Let me a little time to digest the details of irq timings and obtain some data to see if it's suitable for my case. Thanks, -Aubrey
Re: [PATCH] mm, vmscan: do not loop on too_many_isolated for ever
On Mon, 10 Jul 2017, Michal Hocko wrote: > From: Michal Hocko > > Tetsuo Handa has reported [1][2][3]that direct reclaimers might get stuck > in too_many_isolated loop basically for ever because the last few pages > on the LRU lists are isolated by the kswapd which is stuck on fs locks > when doing the pageout or slab reclaim. This in turn means that there is > nobody to actually trigger the oom killer and the system is basically > unusable. > > too_many_isolated has been introduced by 35cd78156c49 ("vmscan: throttle > direct reclaim when too many pages are isolated already") to prevent > from pre-mature oom killer invocations because back then no reclaim > progress could indeed trigger the OOM killer too early. But since the > oom detection rework 0a0337e0d1d1 ("mm, oom: rework oom detection") > the allocation/reclaim retry loop considers all the reclaimable pages > and throttles the allocation at that layer so we can loosen the direct > reclaim throttling. > > Make shrink_inactive_list loop over too_many_isolated bounded and returns > immediately when the situation hasn't resolved after the first sleep. > Replace congestion_wait by a simple schedule_timeout_interruptible because > we are not really waiting on the IO congestion in this path. > > Please note that this patch can theoretically cause the OOM killer to > trigger earlier while there are many pages isolated for the reclaim > which makes progress only very slowly. This would be obvious from the oom > report as the number of isolated pages are printed there. If we ever hit > this should_reclaim_retry should consider those numbers in the evaluation > in one way or another. > > [1] > http://lkml.kernel.org/r/201602092349.acg81273.osvtmjqhlof...@i-love.sakura.ne.jp > [2] > http://lkml.kernel.org/r/201702212335.djb30777.jofmhsftvlq...@i-love.sakura.ne.jp > [3] > http://lkml.kernel.org/r/201706300914.ceh95859.fmqolvfhjft...@i-love.sakura.ne.jp > > Acked-by: Mel Gorman > Tested-by: Tetsuo Handa > Signed-off-by: Michal Hocko > --- > Hi, > I am resubmitting this patch previously sent here > http://lkml.kernel.org/r/20170307133057.26182-1-mho...@kernel.org. > > Johannes and Rik had some concerns that this could lead to premature > OOM kills. I agree with them that we need a better throttling > mechanism. Until now we didn't give the issue described above a high > priority because it usually required a really insane workload to > trigger. But it seems that the issue can be reproduced also without > having an insane number of competing threads [3]. > > Moreover, the issue also triggers very often while testing heavy memory > pressure and so prevents further development of hardening of that area > (http://lkml.kernel.org/r/201707061948.icj18763.tvfoqfohmjf...@i-love.sakura.ne.jp). > Tetsuo hasn't seen any negative effect of this patch in his oom stress > tests so I think we should go with this simple patch for now and think > about something more robust long term. > > That being said I suggest merging this (after spending the full release > cycle in linux-next) for the time being until we come up with a more > clever solution. > > mm/vmscan.c | 8 +++- > 1 file changed, 7 insertions(+), 1 deletion(-) > > diff --git a/mm/vmscan.c b/mm/vmscan.c > index c15b2e4c47ca..4ae069060ae5 100644 > --- a/mm/vmscan.c > +++ b/mm/vmscan.c > @@ -1713,9 +1713,15 @@ shrink_inactive_list(unsigned long nr_to_scan, struct > lruvec *lruvec, > int file = is_file_lru(lru); > struct pglist_data *pgdat = lruvec_pgdat(lruvec); > struct zone_reclaim_stat *reclaim_stat = &lruvec->reclaim_stat; > + bool stalled = false; > > while (unlikely(too_many_isolated(pgdat, file, sc))) { > - congestion_wait(BLK_RW_ASYNC, HZ/10); > + if (stalled) > + return 0; > + > + /* wait a bit for the reclaimer. */ > + schedule_timeout_interruptible(HZ/10); > + stalled = true; > > /* We are about to die and free our memory. Return now. */ > if (fatal_signal_pending(current)) > -- You probably won't welcome getting into alternatives at this late stage; but after hacking around it one way or another because of its pointless lockups, I lost patience with that too_many_isolated() loop a few months back (on realizing the enormous number of pages that may be isolated via migrate_pages(2)), and we've been running nicely since with something like: bool got_mutex = false; if (unlikely(too_many_isolated(pgdat, file, sc))) { if (mutex_lock_killable(&pgdat->too_many_isolated)) return SWAP_CLUSTER_MAX; got_mutex = true; } ... if (got_mutex) mutex_unlock(&pgdat->too_many_isolated); Using a mutex to provide the intended throttling, without an infinite loop or an arbitrary delay; and without having to worry (as we often did) about whether those number
[PATCH] ACPI / PM / EC: Flush all EC work in acpi_freeze_sync()
From: Rafael J. Wysocki Commit eed4d47efe95 (ACPI / sleep: Ignore spurious SCI wakeups from suspend-to-idle) introduced acpi_freeze_sync() whose purpose is to flush all of the processing of possible wakeup events signaled via the ACPI SCI. However, it doesn't flush the query workqueue used by the EC driver, so the events generated by the EC may not be processed timely which leads to issues (increased overhead at least, lost events possibly). To fix that introduce acpi_ec_flush_work() that will flush all of the outstanding EC work and call it from acpi_freeze_sync(). Fixes: eed4d47efe95 (ACPI / sleep: Ignore spurious SCI wakeups from suspend-to-idle) Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c |8 drivers/acpi/internal.h |4 drivers/acpi/sleep.c|6 +++--- 3 files changed, 15 insertions(+), 3 deletions(-) Index: linux-pm/drivers/acpi/ec.c === --- linux-pm.orig/drivers/acpi/ec.c +++ linux-pm/drivers/acpi/ec.c @@ -539,6 +539,14 @@ static void acpi_ec_disable_event(struct spin_unlock_irqrestore(&ec->lock, flags); __acpi_ec_flush_event(ec); } + +void acpi_ec_flush_work(void) +{ + if (first_ec) + __acpi_ec_flush_event(first_ec); + + flush_scheduled_work(); +} #endif /* CONFIG_PM_SLEEP */ static bool acpi_ec_guard_event(struct acpi_ec *ec) Index: linux-pm/drivers/acpi/internal.h === --- linux-pm.orig/drivers/acpi/internal.h +++ linux-pm/drivers/acpi/internal.h @@ -193,6 +193,10 @@ int acpi_ec_add_query_handler(struct acp void *data); void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit); +#ifdef CONFIG_PM_SLEEP +void acpi_ec_flush_work(void); +#endif + /*-- Suspend/Resume Index: linux-pm/drivers/acpi/sleep.c === --- linux-pm.orig/drivers/acpi/sleep.c +++ linux-pm/drivers/acpi/sleep.c @@ -777,11 +777,11 @@ static void acpi_freeze_sync(void) /* * Process all pending events in case there are any wakeup ones. * -* The EC driver uses the system workqueue, so that one needs to be -* flushed too. +* The EC driver uses the system workqueue and an additional special +* one, so those need to be flushed too. */ + acpi_ec_flush_work(); acpi_os_wait_events_complete(); - flush_scheduled_work(); s2idle_wakeup = false; }
[PATCH v2 2/3] PM / sleep: Mark suspend/hibernation start and finish
From: Rafael J. Wysocki Regardless of whether or not debug messages from the core system suspend/hibernation code are enabled, it is useful to know when system-wide transitions start and finish (or fail), so print "info" messages at these points. Signed-off-by: Rafael J. Wysocki --- -> v2: Smiplified the messages as suggested by Mark. --- kernel/power/hibernate.c |5 + kernel/power/suspend.c |2 ++ 2 files changed, 7 insertions(+) Index: linux-pm/kernel/power/hibernate.c === --- linux-pm.orig/kernel/power/hibernate.c +++ linux-pm/kernel/power/hibernate.c @@ -692,6 +692,7 @@ int hibernate(void) goto Unlock; } + pr_info("hibernation entry\n"); pm_prepare_console(); error = __pm_notifier_call_chain(PM_HIBERNATION_PREPARE, -1, &nr_calls); if (error) { @@ -762,6 +763,8 @@ int hibernate(void) atomic_inc(&snapshot_device_available); Unlock: unlock_system_sleep(); + pr_info("hibernation exit\n"); + return error; } @@ -868,6 +871,7 @@ static int software_resume(void) goto Unlock; } + pr_info("resume from hibernation\n"); pm_prepare_console(); error = __pm_notifier_call_chain(PM_RESTORE_PREPARE, -1, &nr_calls); if (error) { @@ -884,6 +888,7 @@ static int software_resume(void) Finish: __pm_notifier_call_chain(PM_POST_RESTORE, nr_calls, NULL); pm_restore_console(); + pr_info("resume from hibernation failed (%d)\n", error); atomic_inc(&snapshot_device_available); /* For success case, the suspend path will release the lock */ Unlock: Index: linux-pm/kernel/power/suspend.c === --- linux-pm.orig/kernel/power/suspend.c +++ linux-pm/kernel/power/suspend.c @@ -579,6 +579,7 @@ int pm_suspend(suspend_state_t state) if (state <= PM_SUSPEND_ON || state >= PM_SUSPEND_MAX) return -EINVAL; + pr_info("PM: suspend entry (%s)\n", pm_states[state]); error = enter_state(state); if (error) { suspend_stats.fail++; @@ -586,6 +587,7 @@ int pm_suspend(suspend_state_t state) } else { suspend_stats.success++; } + pr_info("PM: suspend exit\n"); return error; } EXPORT_SYMBOL(pm_suspend);
[lkp-robot] [include/linux/string.h] 6974f0c455: kernel_BUG_at_lib/string.c
FYI, we noticed the following commit: commit: 6974f0c4555e285ab217cee58b6e874f776ff409 ("include/linux/string.h: add the option of fortified string.h functions") https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git master in testcase: boot on test machine: qemu-system-i386 -enable-kvm -m 256M caused below changes (please refer to attached dmesg/kmsg for entire log/backtrace): [8.134860] kernel BUG at lib/string.c:985! [8.134860] kernel BUG at lib/string.c:985! [8.134863] invalid opcode: [#1] SMP DEBUG_PAGEALLOC [8.134863] invalid opcode: [#1] SMP DEBUG_PAGEALLOC [8.134864] Modules linked in: [8.134864] Modules linked in: [8.134867] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.12.0-10998-g6974f0c #2 [8.134867] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.12.0-10998-g6974f0c #2 [8.134869] task: 8005c000 task.stack: 8005e000 [8.134869] task: 8005c000 task.stack: 8005e000 [8.134872] EIP: fortify_panic+0xe/0x10 [8.134872] EIP: fortify_panic+0xe/0x10 [8.134873] EFLAGS: 00210246 CPU: 0 [8.134873] EFLAGS: 00210246 CPU: 0 [8.134875] EAX: 0022 EBX: 89d33e08 ECX: 0003 EDX: 784c6e40 [8.134875] EAX: 0022 EBX: 89d33e08 ECX: 0003 EDX: 784c6e40 [8.134876] ESI: 0006 EDI: 8be97ffc EBP: 8005fe3c ESP: 8005fe34 [8.134876] ESI: 0006 EDI: 8be97ffc EBP: 8005fe3c ESP: 8005fe34 [8.134878] DS: 007b ES: 007b FS: 00d8 GS: SS: 0068 [8.134878] DS: 007b ES: 007b FS: 00d8 GS: SS: 0068 [8.134879] CR0: 80050033 CR2: CR3: 0c67a000 CR4: 0690 [8.134879] CR0: 80050033 CR2: CR3: 0c67a000 CR4: 0690 [8.134882] Call Trace: [8.134882] Call Trace: [8.134886] arch_prepare_optimized_kprobe+0xd5/0x171 [8.134886] arch_prepare_optimized_kprobe+0xd5/0x171 [8.134887] ? 0x90a2c000 [8.134887] ? 0x90a2c000 [8.134889] ? 0x90a2c000 [8.134889] ? 0x90a2c000 [8.134893] ? 0x90a2c02a [8.134893] ? 0x90a2c02a [8.134894] ? 0x90a2c039 [8.134894] ? 0x90a2c039 [8.134895] ? 0x90a2c02f [8.134895] ? 0x90a2c02f [8.134898] alloc_aggr_kprobe+0x3a/0x44 [8.134898] alloc_aggr_kprobe+0x3a/0x44 [8.134900] register_kprobe+0x366/0x3ca [8.134900] register_kprobe+0x366/0x3ca [8.134903] init_test_probes+0x43/0x41e [8.134903] init_test_probes+0x43/0x41e [8.134905] ? register_module_notifier+0xf/0x11 [8.134905] ? register_module_notifier+0xf/0x11 [8.134909] init_kprobes+0x25d/0x284 [8.134909] init_kprobes+0x25d/0x284 [8.134912] ? debugfs_kprobe_init+0xee/0xee [8.134912] ? debugfs_kprobe_init+0xee/0xee [8.134914] do_one_initcall+0x7e/0x121 [8.134914] do_one_initcall+0x7e/0x121 [8.134916] ? parse_args+0x1a8/0x29b [8.134916] ? parse_args+0x1a8/0x29b [8.134921] ? kernel_init_freeable+0xfd/0x1f8 [8.134921] ? kernel_init_freeable+0xfd/0x1f8 [8.134923] kernel_init_freeable+0x131/0x1f8 [8.134923] kernel_init_freeable+0x131/0x1f8 [8.134926] ? rest_init+0xe6/0xe6 [8.134926] ? rest_init+0xe6/0xe6 [8.134928] kernel_init+0x8/0xd0 [8.134928] kernel_init+0x8/0xd0 [8.134932] ret_from_fork+0x19/0x24 [8.134932] ret_from_fork+0x19/0x24 [8.134936] Code: e0 83 e1 07 01 d1 39 cb 74 09 89 f0 3a 03 75 05 43 eb f3 31 db 5a 89 d8 5b 5e 5f 5d c3 55 89 e5 50 68 03 df 3e 8c e8 71 8f c9 ff <0f> 0b 55 31 c9 89 e5 56 53 89 d3 89 c6 89 c2 3b 1b 74 16 0f ff [8.134936] Code: e0 83 e1 07 01 d1 39 cb 74 09 89 f0 3a 03 75 05 43 eb f3 31 db 5a 89 d8 5b 5e 5f 5d c3 55 89 e5 50 68 03 df 3e 8c e8 71 8f c9 ff <0f> 0b 55 31 c9 89 e5 56 53 89 d3 89 c6 89 c2 3b 1b 74 16 0f ff [8.134973] EIP: fortify_panic+0xe/0x10 SS:ESP: 0068:8005fe34 [8.134973] EIP: fortify_panic+0xe/0x10 SS:ESP: 0068:8005fe34 [8.134976] ---[ end trace 897c8f39c79b92e0 ]--- To reproduce: git clone https://github.com/01org/lkp-tests.git cd lkp-tests bin/lkp qemu -k job-script # job-script is attached in this email Thanks, Xiaolong # # Automatically generated file; DO NOT EDIT. # Linux/i386 4.12.0 Kernel Configuration # # CONFIG_64BIT is not set CONFIG_X86_32=y CONFIG_X86=y CONFIG_INSTRUCTION_DECODER=y CONFIG_OUTPUT_FORMAT="elf32-i386" CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig" CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_MMU=y CONFIG_ARCH_MMAP_RND_BITS_MIN=8 CONFIG_ARCH_MMAP_RND_BITS_MAX=16 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_HWEIGHT=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_HAS_CPU_RELAX=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_WANT_H
[PATCH] staging: rtl8188eu: Move { after function to new line
Fix an error detected by checkpatch.pl on line 75 and move the opening brace after the function signature to a new line. Signed-off-by: Munir Contractor --- drivers/staging/rtl8188eu/include/rtw_ioctl.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/include/rtw_ioctl.h b/drivers/staging/rtl8188eu/include/rtw_ioctl.h index 0fa78ed2c1ab..4c925e610997 100644 --- a/drivers/staging/rtl8188eu/include/rtw_ioctl.h +++ b/drivers/staging/rtl8188eu/include/rtw_ioctl.h @@ -75,7 +75,8 @@ struct oid_par_priv { }; #if defined(_RTW_MP_IOCTL_C_) -static int oid_null_function(struct oid_par_priv *poid_par_priv) { +static int oid_null_function(struct oid_par_priv *poid_par_priv) +{ return NDIS_STATUS_SUCCESS; } #endif -- 2.13.1
Re: [RFC PATCH v1 00/11] Create fast idle path for short idle periods
On 2017/7/19 22:48, Paul E. McKenney wrote: > On Wed, Jul 19, 2017 at 01:44:06PM +0800, Li, Aubrey wrote: >> On 2017/7/18 23:20, Paul E. McKenney wrote: >> 2) for rcu idle enter/exit, I measured the details which Paul provided, and the result matches with what I have measured before, nothing notable found. But it still makes more sense if we can make rcu idle enter/exit hooked with tick off. (it's possible other workloads behave differently) >>> >>> Again, assuming that RCU is informed of CPUs in the kernel, regardless >>> of whether or not the tick is on that that point in time. >>> >> Yeah, I see, no problem for a normal idle. >> >> But for a short idle, we want to return to the task ASAP. Even though RCU >> cost >> is not notable, it would still be better for me if we can save some cycles in >> idle entry and idle exit. >> >> Do we have any problem if we skip RCU idle enter/exit under a fast idle >> scenario? >> My understanding is, if tick is not stopped, then we don't need inform RCU in >> idle path, it can be informed in irq exit. > > Indeed, the problem arises when the tick is stopped. My question is, does problem arise when the tick is *not* stopped (skipping nohz idle)? instead of static void cpuidle_idle_call() { rcu_idle_enter() .. rcu_idle_exit() } I want static void cpuidle_idle_call() { if (tick stopped) rcu_idle_enter() .. if (tick stopped) rcu_idle_exit() } Or checking tick stop can be put into rcu_idle_enter/exit Thanks, -Aubrey
Re: [PATCH v3 04/15] selinux: Refactor to remove bprm_secureexec hook
On Wed, Jul 19, 2017 at 5:19 PM, Paul Moore wrote: > On Wed, Jul 19, 2017 at 8:03 PM, Paul Moore wrote: >> On Tue, Jul 18, 2017 at 6:25 PM, Kees Cook wrote: >>> The SELinux bprm_secureexec hook can be merged with the bprm_set_creds >>> hook since it's dealing with the same information, and all of the details >>> are finalized during the first call to the bprm_set_creds hook via >>> prepare_binprm() (subsequent calls due to binfmt_script, etc, are ignored >>> via bprm->called_set_creds). >>> >>> Here, the test can just happen at the end of the bprm_set_creds hook, >>> and the bprm_secureexec hook can be dropped. >>> >>> Cc: Paul Moore >>> Cc: Stephen Smalley >>> Signed-off-by: Kees Cook >>> --- >>> security/selinux/hooks.c | 24 +--- >>> 1 file changed, 5 insertions(+), 19 deletions(-) >> >> This seems reasonable in the context of the other changes. >> >> Stephen just posted an AT_SECURE test for the selinux-testsuite on the >> SELinux mailing list, it would be nice to ensure that this patchset >> doesn't run afoul of that. > > Quick follow-up: I just merged Stephen's test into the test suite: > > * https://github.com/SELinuxProject/selinux-testsuite Is there a quick how-to on just running the AT_SECURE test? -Kees -- Kees Cook Pixel Security
[PATCH] scripts/dtc: dtx_diff - update include dts paths to match build
From: Frank Rowand Update the cpp include flags for compiling device tree dts files to match the changes made to the kernel build process in commit d5d332d3f7e8 ("devicetree: Move include prefixes from arch to separate directory"). Cc: # 4.12 Signed-off-by: Frank Rowand --- scripts/dtc/dtx_diff | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dtc/dtx_diff b/scripts/dtc/dtx_diff index fb86f3899e16..f9a3d8d23c64 100755 --- a/scripts/dtc/dtx_diff +++ b/scripts/dtc/dtx_diff @@ -321,7 +321,7 @@ fi cpp_flags="\ -nostdinc \ -I${srctree}/arch/${ARCH}/boot/dts \ - -I${srctree}/arch/${ARCH}/boot/dts/include \ + -I${srctree}/scripts/dtc/include-prefixes \ -I${srctree}/drivers/of/testcase-data \ -undef -D__DTS__" -- Frank Rowand
Re: [PATCH] documentation: Fix two-CPU control-dependency example
On Wed, Jul 19, 2017 at 02:56:02PM -0700, Paul E. McKenney wrote: > On Thu, Jul 20, 2017 at 06:33:26AM +0900, Akira Yokosawa wrote: > > On 2017/07/20 2:43, Paul E. McKenney wrote: > > > On Mon, Jul 17, 2017 at 05:24:42PM +0900, Akira Yokosawa wrote: > > >> >From b798b9b631e237d285aa8699da00bfb8ced33bea Mon Sep 17 00:00:00 2001 > > >> From: Akira Yokosawa > > >> Date: Mon, 17 Jul 2017 16:25:33 +0900 > > >> Subject: [PATCH] documentation: Fix two-CPU control-dependency example > > >> > > >> In commit 5646f7acc95f ("memory-barriers: Fix control-ordering > > >> no-transitivity example"), the operator in "if" statement of > > >> the two-CPU example was modified from ">=" to ">". > > >> Now the example misses the point because there is no party > > >> who will modify "x" nor "y". So each CPU performs only the > > >> READ_ONCE(). > > >> > > >> The point of this example is to use control dependency for ordering, > > >> and the WRITE_ONCE() should always be executed. > > >> > > >> So it was correct prior to the above mentioned commit. Partial > > >> revert of the commit (with context adjustments regarding other > > >> changes thereafter) restores the point. > > >> > > >> Note that the three-CPU example demonstrating the lack of > > >> transitivity stands regardless of this partial revert. > > >> > > >> Signed-off-by: Akira Yokosawa > > > > > > Hello, Akira, > > > > > > You are quite right that many compilers would generate straightforward > > > code for the code fragment below, and in that case, the assertion could > > > never trigger due to either TSO or control dependencies, depending on > > > the architecture this was running on. > > > > > > However, if the compiler was too smart for our good, it could figure > > > out that "x" and "y" only take on the values zero and one, so that > > > the "if" would always be taken. At that point, the compiler could > > > simply ignore the "if" with the result shown below. > > > > > >> --- > > >> Documentation/memory-barriers.txt | 2 +- > > >> 1 file changed, 1 insertion(+), 1 deletion(-) > > >> > > >> diff --git a/Documentation/memory-barriers.txt > > >> b/Documentation/memory-barriers.txt > > >> index c4ddfcd..c1ebe99 100644 > > >> --- a/Documentation/memory-barriers.txt > > >> +++ b/Documentation/memory-barriers.txt > > >> @@ -851,7 +851,7 @@ demonstrated by two related examples, with the > > >> initial values of > > >> CPU 0 CPU 1 > > >> === === > > >> r1 = READ_ONCE(x);r2 = READ_ONCE(y); > > >> -if (r1 > 0) if (r2 > 0) > > >> +if (r1 >= 0) if (r2 >= 0) > > >>WRITE_ONCE(y, 1); WRITE_ONCE(x, 1); > > >> > > >> assert(!(r1 == 1 && r2 == 1)); > > > > > > Original program: > > > > > > CPU 0 CPU 1 > > > === === > > > r1 = READ_ONCE(x);r2 = READ_ONCE(y); > > > if (r1 >= 0) if (r2 >= 0) > > > WRITE_ONCE(y, 1); WRITE_ONCE(x, 1); > > > > > > assert(!(r1 == 1 && r2 == 1)); > > > > > > Enthusiastically optimized program: > > > > > > CPU 0 CPU 1 > > > === === > > > r1 = READ_ONCE(x);r2 = READ_ONCE(y); > > > WRITE_ONCE(y, 1); WRITE_ONCE(x, 1); > > > > > > assert(!(r1 == 1 && r2 == 1)); > > > > > > This optimized version could trigger the assertion. > > > > > > So we do need to stick with the ">" comparison. > > > > Well but, > > > > Current example: > > > > CPU 0 CPU 1 > > === === > > r1 = READ_ONCE(x);r2 = READ_ONCE(y); > > if (r1 > 0) if (r2 > 0) > > WRITE_ONCE(y, 1); WRITE_ONCE(x, 1); > > > > assert(!(r1 == 1 && r2 == 1)); > > > > Such a clever compiler might be able to prove that "x" and "y" > > are never modified and end up in the following: > > Hi Akira, I wouldn't call that compiler a clever one, it's a broken one ;-) So here is the thing: READ_ONCE() is a *volatile* load, which means the compiler has to generate code that actually does a load, so the values of r1 and r2 depend on the loads, therefore, a sane compiler will not optimize the if()s out because the volatile semantics of READ_ONCE(). Otherwise, I think we have a lot more to worry about than this case. > > CPU 0 CPU 1 > > === === > > r1 = READ_ONCE(x);r2 = READ_ONCE(y); > > > > assert(!(r1 == 1 && r2 == 1)); > > > > This means it is impossible to describe this example in C, > > doesn't it? > > That is a matter of some debate, but it has gotten increasingly more > difficult to get C to do one's bidding over the decades. > > > What am I missing here? > > The compiler has to work harder in your example case, so it is probably > just
Re: [RFC PATCH v2 3/3] pmbus: Add MAX31785 driver
On Wed, 2017-07-19 at 11:11 -0700, Guenter Roeck wrote: > On Thu, Jul 20, 2017 at 12:35:09AM +0930, Joel Stanley wrote: > > > > On Tue, Jul 18, 2017 at 1:06 PM, Andrew Jeffery wrote: > > > The driver features fan control and basic dual-tachometer support. > > > > Say something about the hardware? > > > > max31785 is a fancy fan controller with temp measurement, pwm, tach, > > breakfast making from Maxim. > > > > > > > > > > The fan control makes use of the new virtual registers exposed by the > > > pmbus core, mixing use of the default implementations with some > > > overrides via the read/write handlers. FAN_COMMAND_1 on the MAX31785 > > > breaks the values into bands that depend on the RPM or PWM control mode. > > > > > > The dual tachometer feature is implemented in hardware with a TACHSEL > > > input to indicate the rotor under measurement, and exposed on the bus by > > > extending the READ_FAN_SPEED_1 word with two extra bytes*. > > > The need to read the non-standard four-byte response leads to a cut-down > > > implementation of i2c_smbus_xfer_emulated() included in the driver. > > > Further, to expose the second rotor tachometer value to userspace, > > > virtual fans are implemented by re-routing the FAN_CONFIG_1_2 register > > > from the undefined (in hardware) pages 23-28 to the same register on > > > pages 0-5, and similarly re-routing READ_FAN_SPEED_1 requests on 23-28 > > > to pages 0-5 but extracting the second word of the four-byte response. > > > > > > * The documentation recommends the slower rotor be associated with > > > TACHSEL=0, which is the input used by the controller's closed-loop fan > > > management. > > > > > > > > > Signed-off-by: Andrew Jeffery > > > --- > > > v1 -> v2: > > > > > > * Implement in terms of virtual registers > > > * Add support for dual-tachometer readings through 'virtual fans' (unused > > > pages) > > > > > > drivers/hwmon/pmbus/Kconfig| 10 ++ > > > drivers/hwmon/pmbus/Makefile | 1 + > > > drivers/hwmon/pmbus/max31785.c | 372 > > > + > > > 3 files changed, 383 insertions(+) > > > create mode 100644 drivers/hwmon/pmbus/max31785.c > > > > > > diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig > > > index cad1229b7e17..5f2f3c6c7499 100644 > > > --- a/drivers/hwmon/pmbus/Kconfig > > > +++ b/drivers/hwmon/pmbus/Kconfig > > > @@ -95,6 +95,16 @@ config SENSORS_MAX20751 > > > This driver can also be built as a module. If so, the module > > > will > > > be called max20751. > > > > > > +config SENSORS_MAX31785 > > > + tristate "Maxim MAX31785 and compatibles" > > > + default n > > > + help > > > + If you say yes here you get hardware monitoring support for > > > Maxim > > > + MAX31785. > > > + > > > + This driver can also be built as a module. If so, the module > > > will > > > + be called max31785. > > > + > > > config SENSORS_MAX34440 > > > tristate "Maxim MAX34440 and compatibles" > > > default n > > > diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile > > > index 562132054aaf..4ea548a8af46 100644 > > > --- a/drivers/hwmon/pmbus/Makefile > > > +++ b/drivers/hwmon/pmbus/Makefile > > > @@ -10,6 +10,7 @@ obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o > > > obj-$(CONFIG_SENSORS_LTC3815) += ltc3815.o > > > obj-$(CONFIG_SENSORS_MAX16064) += max16064.o > > > obj-$(CONFIG_SENSORS_MAX20751) += max20751.o > > > +obj-$(CONFIG_SENSORS_MAX31785) += max31785.o > > > obj-$(CONFIG_SENSORS_MAX34440) += max34440.o > > > obj-$(CONFIG_SENSORS_MAX8688) += max8688.o > > > obj-$(CONFIG_SENSORS_TPS40422) += tps40422.o > > > diff --git a/drivers/hwmon/pmbus/max31785.c > > > b/drivers/hwmon/pmbus/max31785.c > > > new file mode 100644 > > > index ..1baa961f2eb1 > > > --- /dev/null > > > +++ b/drivers/hwmon/pmbus/max31785.c > > > @@ -0,0 +1,372 @@ > > > +/* > > > + * Copyright (C) 2017 IBM Corp. > > > + * > > > + * This program is free software; you can redistribute it and/or modify > > > + * it under the terms of the GNU General Public License as published by > > > + * the Free Software Foundation; either version 2 of the License, or > > > + * (at your option) any later version. > > > + */ > > > + > > > +#include > > > +#include > > > +#include > > > +#include > > > +#include > > > +#include "pmbus.h" > > > + > > > +#define MFR_FAN_CONFIG_DUAL_TACH BIT(12) > > > +#define MFR_FAN_CONFIG_TSFOBIT(9) > > > +#define MFR_FAN_CONFIG_TACHO BIT(8) > > > + > > > +#define MAX31785_CAP_DUAL_TACH BIT(0) > > > + > > > +struct max31785 { > > > + struct pmbus_driver_info info; > > > + > > > + u32 capabilities; > > > +}; > > > + > > > +enum max31785_regs { > > > + PMBUS_MFR_FAN_CONFIG= 0xF1, > > > + PMBUS_MFR_READ_FAN_PWM = 0xF3, > > > + PMBUS_MFR_FAN_FAULT_LIMIT = 0xF5, > > > + PMBUS_MFR_FAN_
linux-next: manual merge of the drm-misc tree with the drm-intel tree
Hi all, Today's linux-next merge of the drm-misc tree got a conflict in: drivers/gpu/drm/i915/i915_drv.c between commit: 99c539bef538 ("drm/i915: unregister interfaces first in unload") from the drm-intel tree and commit: baf54385af78 ("drm/i915: Drop drm_vblank_cleanup") from the drm-misc tree. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc drivers/gpu/drm/i915/i915_drv.c index f406aec8a499,04d9bd84ee43.. --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@@ -1386,8 -1367,8 +1384,6 @@@ void i915_driver_unload(struct drm_devi intel_gvt_cleanup(dev_priv); - drm_vblank_cleanup(dev); - i915_driver_unregister(dev_priv); -- intel_modeset_cleanup(dev); /*
Re: [PATCH] mm/vmalloc: add vm_struct for vm_map_ram area
update the comment bellow as ...'s/by one driver's allocating/because one driver has allocated/'..., sorry for the confusion On Thu, Jul 20, 2017 at 9:15 AM, Zhaoyang Huang wrote: > On Thu, Jul 20, 2017 at 4:50 AM, Andrew Morton > wrote: >> On Wed, 19 Jul 2017 18:44:03 +0800 Zhaoyang Huang >> wrote: >> >>> /proc/vmallocinfo will not show the area allocated by vm_map_ram, which >>> will make confusion when debug. Add vm_struct for them and show them in >>> proc. >>> >> >> Please provide sample /proc/vmallocinfo so we can better understand the >> proposal. Is there a means by which people can determine that a >> particular area is from vm_map_ram()? I don't think so. Should there >> be? > Here is the part of vmallocinfo, the line start with '>' are the ones > allocated by vm_map_ram. > :/ # cat /proc/vmallocinfo > 0xff8000a5f000-0xff8000abb000 376832 > load_module+0x1004/0x1e98 pages=91 vmalloc > 0xff8000ac6000-0xff8000ad2000 49152 > load_module+0x1004/0x1e98 pages=11 vmalloc > 0xff8000ad8000-0xff8000ade000 24576 > load_module+0x1004/0x1e98 pages=5 vmalloc > 0xff800800-0xff80080020008192 of_iomap+0x4c/0x68 > phys=12001000 ioremap > 0xff8008002000-0xff80080040008192 of_iomap+0x4c/0x68 > phys=40356000 ioremap > 0xff8008004000-0xff8008007000 12288 of_iomap+0x4c/0x68 > phys=12002000 ioremap > 0xff8008008000-0xff800800d000 20480 > of_sprd_gates_clk_setup_with_ops+0x88/0x2a8 phys=402b ioremap > 0xff800800e000-0xff8008018192 of_iomap+0x4c/0x68 > phys=40356000 ioremap > ... >>0xff800c5a3000-0xff800c5ec000 299008 shmem_ram_vmap+0xe8/0x1a0 > 0xff800c5fe000-0xff800c608192 > kbasep_js_policy_ctx_has_priority+0x254/0xdb0 [mali_kbase] pages=1 > vmalloc > 0xff800c60-0xff800c701000 1052672 of_iomap+0x4c/0x68 > phys=60d0 ioremap >>0xff800c701000-0xff800c742000 266240 shmem_ram_vmap+0xe8/0x1a0 > 0xff800c74e000-0xff800c758192 > kbasep_js_policy_ctx_has_priority+0x2cc/0xdb0 [mali_kbase] pages=1 > vmalloc > ... >> >>> >>> ... >>> >>> @@ -1173,6 +1178,12 @@ void *vm_map_ram(struct page **pages, unsigned int >>> count, int node, pgprot_t pro >>> addr = (unsigned long)mem; >>> } else { >>> struct vmap_area *va; >>> + struct vm_struct *area; >>> + >>> + area = kzalloc_node(sizeof(*area), GFP_KERNEL, node); >>> + if (unlikely(!area)) >>> + return NULL; >> >> Allocating a vm_struct for each vm_map_ram area is a cost. And we're >> doing this purely for /proc/vmallocinfo. I think I'll need more >> persuading to convince me that this is a good tradeoff, given that >> *every* user will incur this cost, and approximately 0% of them will >> ever use /proc/vmallocinfo. >> >> So... do we *really* need this? If so, why? > The motivation of this commit comes from one practical debug, that is, > vmalloc failed 's/by one driver's allocating/because one driver has > allocated/' a > huge area by vm_map_ram, which can not be traced by cat > /proc/vmallocinfo. We have to add a lot of printk and > dump_stack to get more information. > I don't think the vm_struct cost too much memory, just imagine that > the area got by vmalloc or ioremap instead, you have > to pay for it as well. >>
Re: [RFC PATCH] mm, oom: allow oom reaper to race with exit_mmap
On Wed, 19 Jul 2017, Michal Hocko wrote: > On Thu 29-06-17 10:46:21, Michal Hocko wrote: > > Forgot to CC Hugh. > > > > Hugh, Andrew, do you see this could cause any problem wrt. > > ksm/khugepaged exit path? > > ping. I would really appreciate some help here. I would like to resend > the patch soon. Sorry, Michal, I've been hiding from everyone. No, I don't think your patch will cause any trouble for the ksm or khugepaged exit path; but we'll find out for sure when akpm puts it in mmotm - I doubt I'll get to trying it out in advance of that. On the contrary, I think it will allow us to remove the peculiar "down_write(mmap_sem); up_write(mmap_sem);" from those exit paths: which were there to serialize, precisely because exit_mmap() did not otherwise take mmap_sem; but you're now changing it to do so. You could add a patch to remove those yourself, or any of us add that on afterwards. But I don't entirely agree (or disagree) with your placement: see comment below. > > > On Mon 26-06-17 15:03:46, Michal Hocko wrote: > > > From: Michal Hocko > > > > > > David has noticed that the oom killer might kill additional tasks while > > > the existing victim hasn't terminated yet because the oom_reaper marks > > > the curent victim MMF_OOM_SKIP too early when mm->mm_users dropped down > > > to 0. The race is as follows > > > > > > oom_reap_task do_exit > > > exit_mm > > > __oom_reap_task_mm > > > mmput > > > __mmput > > > mmget_not_zero # fails > > > exit_mmap # frees memory > > > set_bit(MMF_OOM_SKIP) > > > > > > Currently we are try to reduce a risk of this race by taking oom_lock > > > and wait for out_of_memory sleep while holding the lock to give the > > > victim some time to exit. This is quite suboptimal approach because > > > there is no guarantee the victim (especially a large one) will manage > > > to unmap its address space and free enough memory to the particular oom > > > domain which needs a memory (e.g. a specific NUMA node). > > > > > > Fix this problem by allowing __oom_reap_task_mm and __mmput path to > > > race. __oom_reap_task_mm is basically MADV_DONTNEED and that is allowed > > > to run in parallel with other unmappers (hence the mmap_sem for read). > > > The only tricky part is we have to exclude page tables tear down and all > > > operations which modify the address space in the __mmput path. exit_mmap > > > doesn't expect any other users so it doesn't use any locking. Nothing > > > really forbids us to use mmap_sem for write, though. In fact we are > > > already relying on this lock earlier in the __mmput path to synchronize > > > with ksm and khugepaged. > > > > > > Take the exclusive mmap_sem when calling free_pgtables and destroying > > > vmas to sync with __oom_reap_task_mm which take the lock for read. All > > > other operations can safely race with the parallel unmap. > > > > > > Reported-by: David Rientjes > > > Fixes: 26db62f179d1 ("oom: keep mm of the killed task available") > > > Signed-off-by: Michal Hocko > > > --- > > > > > > Hi, > > > I am sending this as an RFC because I am not yet sure I haven't missed > > > something subtle here but the appoach should work in principle. I have > > > run it through some of my OOM stress tests to see if anything blows up > > > and it all went smoothly. > > > > > > The issue has been brought up by David [1]. There were some attempts to > > > address it in oom proper [2][3] but the first one would cause problems > > > on their own [4] while the later is just too hairy. > > > > > > Thoughts, objections, alternatives? > > > > > > [1] > > > http://lkml.kernel.org/r/alpine.deb.2.10.1706141632100.93...@chino.kir.corp.google.com > > > [2] > > > http://lkml.kernel.org/r/201706171417.jhg48401.joqlhmfsvoo...@i-love.sakura.ne.jp > > > [3] > > > http://lkml.kernel.org/r/201706220053.v5m0rmou078...@www262.sakura.ne.jp > > > [4] > > > http://lkml.kernel.org/r/201706210217.v5l2hazc081...@www262.sakura.ne.jp > > > > > > mm/mmap.c | 7 +++ > > > mm/oom_kill.c | 40 ++-- > > > 2 files changed, 9 insertions(+), 38 deletions(-) > > > > > > diff --git a/mm/mmap.c b/mm/mmap.c > > > index 3bd5ecd20d4d..253808e716dc 100644 > > > --- a/mm/mmap.c > > > +++ b/mm/mmap.c > > > @@ -2962,6 +2962,11 @@ void exit_mmap(struct mm_struct *mm) > > > /* Use -1 here to ensure all VMAs in the mm are unmapped */ > > > unmap_vmas(&tlb, vma, 0, -1); > > > > > > + /* > > > + * oom reaper might race with exit_mmap so make sure we won't free > > > + * page tables or unmap VMAs under its feet > > > + */ > > > + down_write(&mm->mmap_sem); Hmm. I'm conflicted about this. From a design point of view, I would very much prefer you to take the mmap_sem higher up, maybe just before or after the mmu_notifier_release() o
RE: [PATCH] cpufreq: imx6q: Fix imx6sx low frequency support
Best Regards! Anson Huang > -Original Message- > From: Lucas Stach [mailto:l.st...@pengutronix.de] > Sent: 2017-07-19 6:28 PM > To: Leonard Crestez > Cc: Viresh Kumar ; Rafael J. Wysocki > ; Shawn Guo ; Fabio Estevam > ; linux...@vger.kernel.org; Octavian Purdila > ; Anson Huang ; Jacky > Bai ; A.s. Dong ; > ker...@pengutronix.de; linux-arm-ker...@lists.infradead.org; linux- > ker...@vger.kernel.org > Subject: Re: [PATCH] cpufreq: imx6q: Fix imx6sx low frequency support > > Hi Leonard, > > Am Mittwoch, den 19.07.2017, 12:54 +0300 schrieb Leonard Crestez: > > This patch contains the minimal changes required to support imx6sx OPP > > of > > 198 Mhz. Without this patch cpufreq still reports success but the > > frequency is not changed, the "arm" clock will still be at 39600 in > clk_summary. > > > > In order to do this PLL1 needs to be bypassed but still kept enabled. > > This is required despite the fact that the arm clk is configured to > > come from > > pll2_pfd2 and from the clk framework perspective pll1 and related > > clocks are unused. > > I'm not really an expert for MX6SX, so a little background on why PLL1 needs > to > be kept enabled would help to review this change. Hi, Lucas The PLL1 needs to be enabled is because when ARM_PODF is changed in CCM, we need to check the busy bit of CCM_CDHIPR bit 16 arm_podf_busy, and this bit is sync with PLL1 clock, so if PLL1 NOT enabled, this bit will never get clear. This is hardware requirement. Anson. > > Thanks, > Lucas > > > This patch adds pll1, pll_bypass and pll1_bypass_src clocks to the imx > > cpufreq driver as imx6sx-specific for the bypass logic. > > > > The definition of pll1_sys is changed to imx_clk_fixed_factor so that > > it's never disabled. > > > > Signed-off-by: Leonard Crestez > > --- > > > > Some potential issues: > > > > In theory pll1_sys could be explictly kept enabled from cpufreq. It's > > not clear this would be better since the intention is to never let > > this be disabled. > > > > The new clocks are only added for imx6sx. The frequency changing code > > relies on the fact that the clk API simply does nothing when called > > with a null clk. > > > > Perhaps it might be better to accept ENOENT from clk_get on these new > > clocks instead of checking of_machine_is_compatible. > > > > arch/arm/boot/dts/imx6sx.dtsi | 8 ++-- > > drivers/clk/imx/clk-imx6sx.c| 2 +- > > drivers/cpufreq/imx6q-cpufreq.c | 33 > > + > > 3 files changed, 40 insertions(+), 3 deletions(-) > > > > diff --git a/arch/arm/boot/dts/imx6sx.dtsi > > b/arch/arm/boot/dts/imx6sx.dtsi index f16b9df..4394137 100644 > > --- a/arch/arm/boot/dts/imx6sx.dtsi > > +++ b/arch/arm/boot/dts/imx6sx.dtsi > > @@ -87,9 +87,13 @@ > > <&clks IMX6SX_CLK_PLL2_PFD2>, > > <&clks IMX6SX_CLK_STEP>, > > <&clks IMX6SX_CLK_PLL1_SW>, > > -<&clks IMX6SX_CLK_PLL1_SYS>; > > +<&clks IMX6SX_CLK_PLL1_SYS>, > > +<&clks IMX6SX_CLK_PLL1>, > > +<&clks IMX6SX_PLL1_BYPASS>, > > +<&clks IMX6SX_PLL1_BYPASS_SRC>; > > clock-names = "arm", "pll2_pfd2_396m", "step", > > - "pll1_sw", "pll1_sys"; > > + "pll1_sw", "pll1_sys", "pll1", > > + "pll1_bypass", "pll1_bypass_src"; > > arm-supply = <®_arm>; > > soc-supply = <®_soc>; > > }; > > diff --git a/drivers/clk/imx/clk-imx6sx.c > > b/drivers/clk/imx/clk-imx6sx.c index b5c96de..aa63b92 100644 > > --- a/drivers/clk/imx/clk-imx6sx.c > > +++ b/drivers/clk/imx/clk-imx6sx.c > > @@ -199,7 +199,7 @@ static void __init imx6sx_clocks_init(struct > device_node *ccm_node) > > clk_set_parent(clks[IMX6SX_PLL6_BYPASS], clks[IMX6SX_CLK_PLL6]); > > clk_set_parent(clks[IMX6SX_PLL7_BYPASS], clks[IMX6SX_CLK_PLL7]); > > > > - clks[IMX6SX_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", > "pll1_bypass", base + 0x00, 13); > > + clks[IMX6SX_CLK_PLL1_SYS] = imx_clk_fixed_factor("pll1_sys", > "pll1_bypass", 1, 1); > > clks[IMX6SX_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", > "pll2_bypass", base + 0x30, 13); > > clks[IMX6SX_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", > "pll3_bypass", base + 0x10, 13); > > clks[IMX6SX_CLK_PLL4_AUDIO]= imx_clk_gate("pll4_audio", > "pll4_bypass", base + 0x70, 13); > > diff --git a/drivers/cpufreq/imx6q-cpufreq.c > > b/drivers/cpufreq/imx6q-cpufreq.c index b6edd3c..caf727a 100644 > > --- a/drivers/cpufreq/imx6q-cpufreq.c > > +++ b/drivers/cpufreq/imx6q-cpufreq.c > > @@ -31,6 +31,9 @@ static struct clk *step_clk; static struct clk > > *pll2_pfd2_396m_clk; > > > > /* clk used by i.MX6UL */ > > +static struct clk *pll1_bypass; > > +static struct clk *pll1_bypas
Re: [PATCH] mm/vmalloc: add vm_struct for vm_map_ram area
On Thu, Jul 20, 2017 at 4:50 AM, Andrew Morton wrote: > On Wed, 19 Jul 2017 18:44:03 +0800 Zhaoyang Huang > wrote: > >> /proc/vmallocinfo will not show the area allocated by vm_map_ram, which >> will make confusion when debug. Add vm_struct for them and show them in >> proc. >> > > Please provide sample /proc/vmallocinfo so we can better understand the > proposal. Is there a means by which people can determine that a > particular area is from vm_map_ram()? I don't think so. Should there > be? Here is the part of vmallocinfo, the line start with '>' are the ones allocated by vm_map_ram. :/ # cat /proc/vmallocinfo 0xff8000a5f000-0xff8000abb000 376832 load_module+0x1004/0x1e98 pages=91 vmalloc 0xff8000ac6000-0xff8000ad2000 49152 load_module+0x1004/0x1e98 pages=11 vmalloc 0xff8000ad8000-0xff8000ade000 24576 load_module+0x1004/0x1e98 pages=5 vmalloc 0xff800800-0xff80080020008192 of_iomap+0x4c/0x68 phys=12001000 ioremap 0xff8008002000-0xff80080040008192 of_iomap+0x4c/0x68 phys=40356000 ioremap 0xff8008004000-0xff8008007000 12288 of_iomap+0x4c/0x68 phys=12002000 ioremap 0xff8008008000-0xff800800d000 20480 of_sprd_gates_clk_setup_with_ops+0x88/0x2a8 phys=402b ioremap 0xff800800e000-0xff8008018192 of_iomap+0x4c/0x68 phys=40356000 ioremap ... >0xff800c5a3000-0xff800c5ec000 299008 shmem_ram_vmap+0xe8/0x1a0 0xff800c5fe000-0xff800c608192 kbasep_js_policy_ctx_has_priority+0x254/0xdb0 [mali_kbase] pages=1 vmalloc 0xff800c60-0xff800c701000 1052672 of_iomap+0x4c/0x68 phys=60d0 ioremap >0xff800c701000-0xff800c742000 266240 shmem_ram_vmap+0xe8/0x1a0 0xff800c74e000-0xff800c758192 kbasep_js_policy_ctx_has_priority+0x2cc/0xdb0 [mali_kbase] pages=1 vmalloc ... > >> >> ... >> >> @@ -1173,6 +1178,12 @@ void *vm_map_ram(struct page **pages, unsigned int >> count, int node, pgprot_t pro >> addr = (unsigned long)mem; >> } else { >> struct vmap_area *va; >> + struct vm_struct *area; >> + >> + area = kzalloc_node(sizeof(*area), GFP_KERNEL, node); >> + if (unlikely(!area)) >> + return NULL; > > Allocating a vm_struct for each vm_map_ram area is a cost. And we're > doing this purely for /proc/vmallocinfo. I think I'll need more > persuading to convince me that this is a good tradeoff, given that > *every* user will incur this cost, and approximately 0% of them will > ever use /proc/vmallocinfo. > > So... do we *really* need this? If so, why? The motivation of this commit comes from one practical debug, that is, vmalloc failed by one driver's allocating a huge area by vm_map_ram, which can not be traced by cat /proc/vmallocinfo. We have to add a lot of printk and dump_stack to get more information. I don't think the vm_struct cost too much memory, just imagine that the area got by vmalloc or ioremap instead, you have to pay for it as well. >
Re: [PATCH RESEND v4] MAINTAINERS: fix lots of alphabetic ordering
On Wed, 2017-07-19 at 17:08 -0700, Linus Torvalds wrote: > I can easily just look at the reject and fix it, but I don't really > want to. Why? Because I hate the MAINTAINERS file. > > It's the most painful file for merging too, because everybody touches > it - kind of like the old "one single Kconfig file" was back in the > bad old days. > For example, just during this merge window: > > $ git rev-list --count --no-merges v4.12.. MAINTAINERS > 112 > > and while most of them obviously didn't cause any conflicts (there > were four this cycle), it's still my least favourite "stupid work". > That file pretty consistently gets 100+ changes to it: > > v4.1: 87 > v4.2: 109 > v4.3: 94 > v4.4: 91 > v4.5: 118 > v4.6: 98 > v4.7: 112 > v4.8: 121 > v4.9: 128 > v4.10: 135 > v4.11: 78 > v4.12: 127 > > So I'm wondering if > > (a) we could add a script to do the alphabetical ordering properly. > > (b) we could split this thing up some sane way. > > Anybody got any ideas? > > I'm throwing out _one_ idea: split it up by the main F: line, so that > maintainership information ends up being hierarchical like the Kconfig > files. Teach "get_maintainer.pl" to just do "find . -name > MAINTAINERS" instead? Just for ease of manipulation and not breaking the script much, I'd suggest just having a MAINTAINERS directory and stuffing each of the sections into separate files. The script would only need to add $ cat MAINTAINERS/* as input.
Re: [Intel-gfx] [PATCH] drm/i915: Synchronize connectors states when switching from poll to irq
On Mon, 2017-06-26 at 15:32 +0300, Paul Kocialkowski wrote: > After detecting an IRQ storm, hotplug detection will switch from > irq-based detection to poll-based detection. After a short delay or > when resetting storm detection from debugfs, detection will switch > back to being irq-based. > > However, it may occur that polling does not have enough time to detect > the current connector state when that second switch takes place. Some questions so that I understand this better. How short would this have to be for detect to not complete? Is there a way I can easily test this scenario? > Thus, > this sets the appropriate hotplug event bits for the concerned > connectors and schedules the hotplug work, that will ensure the > connectors states are in sync when switching back to irq. > Not sure I understand this correctly, looks like you are setting the event_bits even if there was no irq during the polling interval. Is that right? > Without this, no irq will be triggered and the hpd change will be lost. > > Signed-off-by: Paul Kocialkowski > --- > drivers/gpu/drm/i915/intel_hotplug.c | 8 +++- > 1 file changed, 7 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/intel_hotplug.c > b/drivers/gpu/drm/i915/intel_hotplug.c > index f1200272a699..29f55480b0bb 100644 > --- a/drivers/gpu/drm/i915/intel_hotplug.c > +++ b/drivers/gpu/drm/i915/intel_hotplug.c > @@ -218,9 +218,13 @@ static void intel_hpd_irq_storm_reenable_work(struct > work_struct *work) > struct intel_connector *intel_connector = > to_intel_connector(connector); > > if (intel_connector->encoder->hpd_pin == i) { > - if (connector->polled != > intel_connector->polled) > + if (connector->polled != > intel_connector->polled) { > DRM_DEBUG_DRIVER("Reenabling HPD on > connector %s\n", >connector->name); > + > + dev_priv->hotplug.event_bits |= (1 << > i); > + } > + > connector->polled = intel_connector->polled; > if (!connector->polled) > connector->polled = > DRM_CONNECTOR_POLL_HPD; > @@ -232,6 +236,8 @@ static void intel_hpd_irq_storm_reenable_work(struct > work_struct *work) > dev_priv->display.hpd_irq_setup(dev_priv); > spin_unlock_irq(&dev_priv->irq_lock); > > + schedule_work(&dev_priv->hotplug.hotplug_work); How does this work with DP connectors? From what I understand, the event_bits are set for DP based on the return value from intel_dp_hpd_pulse(). But, doesn't this patch set the bits unconditionally? > + > intel_runtime_pm_put(dev_priv); > } >
Re: [PATCH RESEND v4] MAINTAINERS: fix lots of alphabetic ordering
On 07/19/2017 05:53 PM, Linus Torvalds wrote: > On Wed, Jul 19, 2017 at 5:35 PM, Linus Torvalds > wrote: >> >> Your mailer is crap, and destroys utf-8 characters. In particular: >> >> -M: MichaÅ‚ MirosÅ‚aw > > Using pseudo-MIME-encoding, that was actually (before my cut-and-paste > mangled it even more): > > Micha=c3=85=c2=82 Miros=c3=85=c2=82aw > >> should be >> >> -M: Michał Mirosław > > And the correct utf-8 is > > Micha=C5=82 Miros=C5=82aw > > and it *looks* like what happened is that something thought the input > was Latin1, and converted the Latin1 to UTF-8. > > So the utf-8 character 'ł' (two bytes: =C5=82) was seen as two Latin1 > character bytes: =c5 and =82. > > And then each of those were converted mindlessly to utf-8, so the 'c5' > character became '=C3=85' and the '82' character became '=c2=82'. > > So you have something that believes that a source file was latin1. > > May I suggest just making absolutely *everything* on your system use a > utf-8 locale? > > Because in this day and age, anything but utf-8 is just woefully > broken crud. "Just say no". Thanks for the diagnosis. Will do. -- ~Randy
[lkp-robot] [platform/x86] bff589be59: kmsg.dell_wmi:Cannot_read_Dell_descriptor_buffer
FYI, we noticed the following commit: commit: bff589be59c50924a9715951160578e570cba5c6 ("platform/x86: dell-wmi: Convert to the WMI bus infrastructure") https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git master in testcase: boot on test machine: qemu-system-x86_64 -enable-kvm -m 420M caused below changes (please refer to attached dmesg/kmsg for entire log/backtrace): [7.102869] usbhid: USB HID core driver [7.104086] dell_wmi: Cannot read Dell descriptor buffer - 1 [7.104088] acer_wmi: Acer Laptop ACPI-WMI Extras [7.104097] acer_wmi: No or unsupported WMI interface, unable to load To reproduce: git clone https://github.com/01org/lkp-tests.git cd lkp-tests bin/lkp qemu -k job-script # job-script is attached in this email Thanks, Xiaolong #!/bin/sh export_top_env() { export suite='boot' export testcase='boot' export timeout='10m' export job_origin='/lkp/lkp/src/jobs/boot.yaml' export queue='bisect' export testbox='vm-lkp-nhm-dp1-openwrt-ia32-4' export tbox_group='vm-lkp-nhm-dp1-openwrt-ia32' export branch='linus/master' export commit='bff589be59c50924a9715951160578e570cba5c6' export kconfig='x86_64-nfsroot' export submit_id='596aafb30b9a931af7e8ffa1' export job_file='/lkp/scheduled/vm-lkp-nhm-dp1-openwrt-ia32-4/boot-1-openwrt-i386-2016-03-16.cgz-bff589be59c50924a9715951160578e570cba5c6-20170716-72439-120txhp-0.yaml' export id='fac0bb4dbf48ec7df35e4ad4d85535a177303e1b' export model='qemu-system-x86_64 -enable-kvm' export nr_vm=10 export nr_cpu=1 export memory='420M' export rootfs='openwrt-i386-2016-03-16.cgz' export need_kconfig='CONFIG_KVM_GUEST=y' export compiler='gcc-6' export enqueue_time='2017-07-16 08:13:39 +0800' export _id='596aafb30b9a931af7e8ffa1' export _rt='/result/boot/1/vm-lkp-nhm-dp1-openwrt-ia32/openwrt-i386-2016-03-16.cgz/x86_64-nfsroot/gcc-6/bff589be59c50924a9715951160578e570cba5c6' export user='lkp' export result_root='/result/boot/1/vm-lkp-nhm-dp1-openwrt-ia32/openwrt-i386-2016-03-16.cgz/x86_64-nfsroot/gcc-6/bff589be59c50924a9715951160578e570cba5c6/0' export LKP_SERVER='inn' export max_uptime=600 export initrd='/osimage/openwrt/openwrt-i386-2016-03-16.cgz' export bootloader_append='root=/dev/ram0 user=lkp job=/lkp/scheduled/vm-lkp-nhm-dp1-openwrt-ia32-4/boot-1-openwrt-i386-2016-03-16.cgz-bff589be59c50924a9715951160578e570cba5c6-20170716-72439-120txhp-0.yaml ARCH=x86_64 kconfig=x86_64-nfsroot branch=linus/master commit=bff589be59c50924a9715951160578e570cba5c6 BOOT_IMAGE=/pkg/linux/x86_64-nfsroot/gcc-6/bff589be59c50924a9715951160578e570cba5c6/vmlinuz-4.12.0-rc1-00039-gbff589b max_uptime=600 RESULT_ROOT=/result/boot/1/vm-lkp-nhm-dp1-openwrt-ia32/openwrt-i386-2016-03-16.cgz/x86_64-nfsroot/gcc-6/bff589be59c50924a9715951160578e570cba5c6/0 LKP_SERVER=inn debug apic=debug sysrq_always_enabled rcupdate.rcu_cpu_stall_timeout=100 net.ifnames=0 printk.devkmsg=on panic=-1 softlockup_panic=1 nmi_watchdog=panic oops=panic load_ramdisk=2 prompt_ramdisk=0 drbd.minor_count=8 systemd.log_level=err ignore_loglevel earlyprintk=ttyS0,115200 console=ttyS0,115200 console=tty0 vga=normal rw' export lkp_initrd='/lkp/lkp/lkp-i386.cgz' export modules_initrd='/pkg/linux/x86_64-nfsroot/gcc-6/bff589be59c50924a9715951160578e570cba5c6/modules.cgz' export site='inn' export LKP_CGI_PORT=80 export LKP_CIFS_PORT=139 export kernel='/pkg/linux/x86_64-nfsroot/gcc-6/bff589be59c50924a9715951160578e570cba5c6/vmlinuz-4.12.0-rc1-00039-gbff589b' export dequeue_time='2017-07-16 08:18:40 +0800' export job_initrd='/lkp/scheduled/vm-lkp-nhm-dp1-openwrt-ia32-4/boot-1-openwrt-i386-2016-03-16.cgz-bff589be59c50924a9715951160578e570cba5c6-20170716-72439-120txhp-0.cgz' [ -n "$LKP_SRC" ] || export LKP_SRC=/lkp/${user:-lkp}/src } run_job() { echo $$ > $TMP/run-job.pid . $LKP_SRC/lib/http.sh . $LKP_SRC/lib/job.sh . $LKP_SRC/lib/env.sh export_top_env run_monitor $LKP_SRC/monitors/one-shot/wrapper boot-slabinfo run_monitor $LKP_SRC/monitors/one-shot/wrapper boot-meminfo run_monitor $LKP_SRC/monitors/one-shot/wrapper memmap run_monitor $LKP_SRC/monitors/wrapper kmsg run_monitor $LKP_SRC/monitors/wrapper oom-killer run_monitor $LKP_SRC/monitors/plain/watchdog run_monitor $LKP_SRC/monitors/wrapper nfs-hang run_test $LKP_SRC/tests/wrapper sleep 1 } extract_stats() { $LKP_SRC/stats/wrapper boot-slabinfo $LKP_SRC/stats/wrapper boot-meminfo $LKP_SRC/stats/wrapper memmap $LKP_SRC/stats/wrapper boot-memory $LKP_SRC/stats/wrapper boot-time $LKP_SRC/stats/wrapper kernel-size $LKP_SRC/stats/wrapper kmsg $L
[lkp-robot] [uuid] df33767d9f: kmsg.test_uuid:failed#out_of#tests
FYI, we noticed the following commit: commit: df33767d9fe0ca93c606cc9042df05e5045c8158 ("uuid: hoist helpers uuid_equal() and uuid_copy() from xfs") https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git master in testcase: boot on test machine: qemu-system-x86_64 -enable-kvm -m 420M caused below changes (please refer to attached dmesg/kmsg for entire log/backtrace): [ 12.54] test_uuid: cmp test #4 failed on BE data: 'c33f4995-3701-450e-9fbf-206a2e98e576' [ 12.54] test_uuid: cmp test #4 failed on BE data: 'c33f4995-3701-450e-9fbf-206a2e98e576' [ 12.543655] test_uuid: cmp test #4 actual data: 'c33f4995-3701-450e-9fbf-206a2e98e576' [ 12.543655] test_uuid: cmp test #4 actual data: 'c33f4995-3701-450e-9fbf-206a2e98e576' [ 12.547454] test_uuid: cmp test #8 failed on BE data: '64b4371c-77c1-48f9-8221-29f054fc023b' [ 12.547454] test_uuid: cmp test #8 failed on BE data: '64b4371c-77c1-48f9-8221-29f054fc023b' [ 12.551521] test_uuid: cmp test #8 actual data: '64b4371c-77c1-48f9-8221-29f054fc023b' [ 12.551521] test_uuid: cmp test #8 actual data: '64b4371c-77c1-48f9-8221-29f054fc023b' [ 12.555092] test_uuid: cmp test #12 failed on BE data: '0cb4ddff-a545-4401-9d06-688af53e7f84' [ 12.555092] test_uuid: cmp test #12 failed on BE data: '0cb4ddff-a545-4401-9d06-688af53e7f84' [ 12.559228] test_uuid: cmp test #12 actual data: '0cb4ddff-a545-4401-9d06-688af53e7f84' [ 12.559228] test_uuid: cmp test #12 actual data: '0cb4ddff-a545-4401-9d06-688af53e7f84' [ 12.562884] test_uuid: failed 3 out of 18 tests [ 12.562884] test_uuid: failed 3 out of 18 tests To reproduce: git clone https://github.com/01org/lkp-tests.git cd lkp-tests bin/lkp qemu -k job-script # job-script is attached in this email Thanks, Xiaolong #!/bin/sh export_top_env() { export suite='boot' export testcase='boot' export timeout='10m' export job_origin='/lkp/lkp/src/jobs/boot.yaml' export queue='bisect' export testbox='vm-lkp-nhm-dp2-yocto-ia32-8' export tbox_group='vm-lkp-nhm-dp2-yocto-ia32' export branch='linus/master' export commit='df33767d9fe0ca93c606cc9042df05e5045c8158' export kconfig='x86_64-randconfig-ne0-07170150' export submit_id='596c1ab60b9a93746d3ee04d' export job_file='/lkp/scheduled/vm-lkp-nhm-dp2-yocto-ia32-8/boot-1-yocto-tiny-i386-2016-04-22.cgz-df33767d9fe0ca93c606cc9042df05e5045c8158-20170717-29805-1dscryj-0.yaml' export id='1688a01d3ec35d6511538587055e9faefa220fa8' export model='qemu-system-x86_64 -enable-kvm' export nr_vm=16 export nr_cpu=1 export memory='420M' export rootfs='yocto-tiny-i386-2016-04-22.cgz' export need_kconfig='CONFIG_KVM_GUEST=y' export compiler='gcc-6' export enqueue_time='2017-07-17 10:02:30 +0800' export _id='596c1ab60b9a93746d3ee04d' export _rt='/result/boot/1/vm-lkp-nhm-dp2-yocto-ia32/yocto-tiny-i386-2016-04-22.cgz/x86_64-randconfig-ne0-07170150/gcc-6/df33767d9fe0ca93c606cc9042df05e5045c8158' export user='lkp' export result_root='/result/boot/1/vm-lkp-nhm-dp2-yocto-ia32/yocto-tiny-i386-2016-04-22.cgz/x86_64-randconfig-ne0-07170150/gcc-6/df33767d9fe0ca93c606cc9042df05e5045c8158/0' export LKP_SERVER='inn' export max_uptime=600 export initrd='/osimage/yocto/yocto-tiny-i386-2016-04-22.cgz' export bootloader_append='root=/dev/ram0 user=lkp job=/lkp/scheduled/vm-lkp-nhm-dp2-yocto-ia32-8/boot-1-yocto-tiny-i386-2016-04-22.cgz-df33767d9fe0ca93c606cc9042df05e5045c8158-20170717-29805-1dscryj-0.yaml ARCH=x86_64 kconfig=x86_64-randconfig-ne0-07170150 branch=linus/master commit=df33767d9fe0ca93c606cc9042df05e5045c8158 BOOT_IMAGE=/pkg/linux/x86_64-randconfig-ne0-07170150/gcc-6/df33767d9fe0ca93c606cc9042df05e5045c8158/vmlinuz-4.12.0-rc4-9-gdf33767 max_uptime=600 RESULT_ROOT=/result/boot/1/vm-lkp-nhm-dp2-yocto-ia32/yocto-tiny-i386-2016-04-22.cgz/x86_64-randconfig-ne0-07170150/gcc-6/df33767d9fe0ca93c606cc9042df05e5045c8158/0 LKP_SERVER=inn debug apic=debug sysrq_always_enabled rcupdate.rcu_cpu_stall_timeout=100 net.ifnames=0 printk.devkmsg=on panic=-1 softlockup_panic=1 nmi_watchdog=panic oops=panic load_ramdisk=2 prompt_ramdisk=0 drbd.minor_count=8 systemd.log_level=err ignore_loglevel earlyprintk=ttyS0,115200 console=ttyS0,115200 console=tty0 vga=normal rw' export lkp_initrd='/lkp/lkp/lkp-i386.cgz' export bm_initrd='/osimage/deps/debian-x86_64-2016-08-31.cgz/run-ipconfig.i386_2016-09-03.cgz' export site='inn' export LKP_CGI_PORT=80 export LKP_CIFS_PORT=139 export kernel='/pkg/linux/x86_64-randconfig-ne0-07170150/gcc-6/df33767d9fe0ca93c606cc9042df05e5045c8158/vmlinuz-4.12.0-rc4-9-gdf33767' export dequeue_time='2017-07-17 10:16:36 +0800' export job_initrd='/lkp/scheduled/vm-lkp-nhm-dp2-yocto-ia32-8/boot-1-yocto-tiny-i386-2016-04-22.
Re: [PATCH RESEND v4] MAINTAINERS: fix lots of alphabetic ordering
On Wed, Jul 19, 2017 at 5:35 PM, Linus Torvalds wrote: > > Your mailer is crap, and destroys utf-8 characters. In particular: > > -M: MichaÅ‚ MirosÅ‚aw Using pseudo-MIME-encoding, that was actually (before my cut-and-paste mangled it even more): Micha=c3=85=c2=82 Miros=c3=85=c2=82aw > should be > > -M: Michał Mirosław And the correct utf-8 is Micha=C5=82 Miros=C5=82aw and it *looks* like what happened is that something thought the input was Latin1, and converted the Latin1 to UTF-8. So the utf-8 character 'ł' (two bytes: =C5=82) was seen as two Latin1 character bytes: =c5 and =82. And then each of those were converted mindlessly to utf-8, so the 'c5' character became '=C3=85' and the '82' character became '=c2=82'. So you have something that believes that a source file was latin1. May I suggest just making absolutely *everything* on your system use a utf-8 locale? Because in this day and age, anything but utf-8 is just woefully broken crud. "Just say no". Linus
Re: [RFC PATCH v2 1/3] hwmon: pmbus: Add fan control support
On Thu, 2017-07-20 at 00:35 +0930, Joel Stanley wrote: > > On Tue, Jul 18, 2017 at 1:06 PM, Andrew Jeffery wrote: > > Expose fanX_target, pwmX and pwmX_enable hwmon sysfs attributes. > > Nice! I had a bit of a read. I'm not a pmbus expert, so most of the > review is nitpicks about types, etc. > > I'll defer to Guenter for the real stuff. Thanks for taking a look. A lot of the issues are a case of overzealous caution so I didn't trip myself up during development. A lot of it can be cleaned up. I won't respond to all of them. > > > > > Fans in a PMBus device are driven by the configuration of two registers: > > FAN_CONFIG_x_y and FAN_COMMAND_x: FAN_CONFIG_x_y dictates how the fan > > and the tacho operate (if installed), while FAN_COMMAND_x sets the > > desired fan rate. The unit of FAN_COMMAND_x is dependent on the > > operational fan mode, RPM or PWM percent duty, as determined by the > > corresponding FAN_CONFIG_x_y. > > > > The mapping of fanX_target, pwmX and pwmX_enable onto FAN_CONFIG_x_y and > > FAN_COMMAND_x is implemented with the addition of virtual registers and > > generic implementations in the core: > > > > 1. PMBUS_VIRT_FAN_TARGET_x > > 2. PMBUS_VIRT_PWM_x > > 3. PMBUS_VIRT_PWM_ENABLE_x > > > > The facilitate the necessary side-effects of each access. Examples of > > the read case, assuming m = 1, b = 0, R = 0: > > > > Read | With || Gives > > --- > > Attribute | FAN_CONFIG_x_y | FAN_COMMAND_y || Value > > --++--- > > fanX_target | ~PB_FAN_z_RPM | 0x0001|| 1 > > pwm1| ~PB_FAN_z_RPM | 0x0064|| 255 > > pwmX_enable | ~PB_FAN_z_RPM | 0x0001|| 1 > > fanX_target | PB_FAN_z_RPM | 0x0001|| 1 > > pwm1| PB_FAN_z_RPM | 0x0064|| 0 > > pwmX_enable | PB_FAN_z_RPM | 0x0001|| 1 > > > > And the write case: > > > > Write| With || Sets > > -+---+++--- > > Attribute | Value || FAN_CONFIG_x_y | FAN_COMMAND_x > > -+---+++--- > > fanX_target | 1 || PB_FAN_z_RPM | 0x0001 > > pwmX| 255 || ~PB_FAN_z_RPM | 0x0064 > > pwmX_enable | 1 || ~PB_FAN_z_RPM | 0x0064 > > > > Also, the DIRECT mode scaling of some controllers is different between > > RPM and PWM percent duty control modes, so PSC_PWM is introduced to > > capture the necessary coefficients. > > > > > > Signed-off-by: Andrew Jeffery > > --- > > > > v1 -> v2: > > * Convert to using virtual registers > > * Drop struct pmbus_fan_ctrl > > * Introduce PSC_PWM > > * Drop struct pmbus_coeffs > > * Drop additional callbacks > > > > drivers/hwmon/pmbus/pmbus.h | 19 > > drivers/hwmon/pmbus/pmbus_core.c | 215 > > +++ > > 2 files changed, 217 insertions(+), 17 deletions(-) > > > > diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h > > index bfcb13bae34b..226a37bd525f 100644 > > --- a/drivers/hwmon/pmbus/pmbus.h > > +++ b/drivers/hwmon/pmbus/pmbus.h > > @@ -190,6 +190,20 @@ enum pmbus_regs { > > PMBUS_VIRT_VMON_UV_FAULT_LIMIT, > > PMBUS_VIRT_VMON_OV_FAULT_LIMIT, > > PMBUS_VIRT_STATUS_VMON, > > + > > + /* Fan control */ > > + PMBUS_VIRT_FAN_TARGET_1, > > + PMBUS_VIRT_FAN_TARGET_2, > > + PMBUS_VIRT_FAN_TARGET_3, > > + PMBUS_VIRT_FAN_TARGET_4, > > + PMBUS_VIRT_PWM_1, > > + PMBUS_VIRT_PWM_2, > > + PMBUS_VIRT_PWM_3, > > + PMBUS_VIRT_PWM_4, > > + PMBUS_VIRT_PWM_ENABLE_1, > > + PMBUS_VIRT_PWM_ENABLE_2, > > + PMBUS_VIRT_PWM_ENABLE_3, > > + PMBUS_VIRT_PWM_ENABLE_4, > > }; > > > > /* > > @@ -223,6 +237,8 @@ enum pmbus_regs { > > #define PB_FAN_1_RPM BIT(6) > > #define PB_FAN_1_INSTALLED BIT(7) > > > > +enum pmbus_fan_mode { percent = 0, rpm }; > > + > > /* > > * STATUS_BYTE, STATUS_WORD (lower) > > */ > > @@ -313,6 +329,7 @@ enum pmbus_sensor_classes { > > PSC_POWER, > > PSC_TEMPERATURE, > > PSC_FAN, > > + PSC_PWM, > > PSC_NUM_CLASSES /* Number of power sensor classes */ > > }; > > > > @@ -413,6 +430,8 @@ int pmbus_write_byte_data(struct i2c_client *client, > > int page, u8 reg, > > u8 value); > > int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, > > u8 mask, u8 value); > > +int pmbus_update_fan(struct i2c_client *client, int page, int id, > > +int config, int mask, int command); > > void pmbus_clear_faults(struct i2c_client *client); > > bool pmbus_check_byte_register(struct i2c_client *client, int page, int > > r
[PATCH] thermal: intel_pch_thermal: Read large temp values correctly
On all supported platforms, the TS Reading (TSR) field in the Temperature (TEMP) register is 9 bits wide. Values above 0x100 (78 degrees C) are plausible, so don't mask out the topmost bit. And the register itself is 16 bits wide, so use readw() rather than readl(). Signed-off-by: Ed Swierk --- drivers/thermal/intel_pch_thermal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/intel_pch_thermal.c b/drivers/thermal/intel_pch_thermal.c index 9889c90..318fc1b 100644 --- a/drivers/thermal/intel_pch_thermal.c +++ b/drivers/thermal/intel_pch_thermal.c @@ -49,7 +49,7 @@ #define WPT_TSGPEN 0x84/* General Purpose Event Enables */ /* Wildcat Point-LP PCH Thermal Register bit definitions */ -#define WPT_TEMP_TSR 0x00ff /* Temp TS Reading */ +#define WPT_TEMP_TSR 0x01ff /* Temp TS Reading */ #define WPT_TSC_CPDE 0x01/* Catastrophic Power-Down Enable */ #define WPT_TSS_TSDSS 0x10/* Thermal Sensor Dynamic Shutdown Status */ #define WPT_TSS_GPES 0x08/* GPE status */ @@ -174,9 +174,9 @@ static int pch_wpt_init(struct pch_thermal_device *ptd, int *nr_trips) static int pch_wpt_get_temp(struct pch_thermal_device *ptd, int *temp) { - u8 wpt_temp; + u16 wpt_temp; - wpt_temp = WPT_TEMP_TSR & readl(ptd->hw_base + WPT_TEMP); + wpt_temp = WPT_TEMP_TSR & readw(ptd->hw_base + WPT_TEMP); /* Resolution of 1/2 degree C and an offset of -50C */ *temp = (wpt_temp * 1000 / 2 - 5); -- 1.9.1
[PATCH V2] pci: quirk: Apply APM ACS quirk to XGene devices
The APM X-Gene PCIe root port does not support ACS at this point. However, the hw provides isolation and source validation through the SMMU. Turn on ACS but disable all the peer to peer features. Signed-off-by: Feng Kan --- drivers/pci/quirks.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 085fb78..0f8f1cd 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4120,6 +4120,19 @@ static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags) return acs_flags ? 0 : 1; } +static int pci_quirk_xgene_acs(struct pci_dev *dev, u16 acs_flags) +{ + /* +* XGene root matching this quirk do not allow peer-to-peer +* transactions with others, allowing masking out these bits as if they +* were unimplemented in the ACS capability. +*/ + acs_flags &= ~(PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR | + PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT); + + return acs_flags ? 0 : 1; +} + /* * Many Intel PCH root ports do provide ACS-like features to disable peer * transactions and validate bus numbers in requests, but do not provide an @@ -4368,6 +4381,8 @@ static int pci_quirk_mf_endpoint_acs(struct pci_dev *dev, u16 acs_flags) { 0x10df, 0x720, pci_quirk_mf_endpoint_acs }, /* Emulex Skyhawk-R */ /* Cavium ThunderX */ { PCI_VENDOR_ID_CAVIUM, PCI_ANY_ID, pci_quirk_cavium_acs }, + /* APM XGene */ + { PCI_VENDOR_ID_AMCC, 0xE004, pci_quirk_xgene_acs }, { 0 } }; -- 1.8.3.1
[PATCH] thermal: intel_pch_thermal: Fix enable check on Broadwell-DE
Using the TSDSS flag to determine whether the thermal sensor is enabled is problematic. Broadwell-DE (Xeon D-1500) does not support dynamic shutdown and the TSDSS flag always reads 0 (contrary to the current datasheet). Even on hardware supporting dynamic shutdown, the driver does nothing to configure it, and the dynamic shutdown state should not prevent the driver from loading. The ETS flag itself indicates whether the thermal sensor is enabled, so use it instead of the TSDSS flag on all hardware platforms. Signed-off-by: Ed Swierk --- drivers/thermal/intel_pch_thermal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/intel_pch_thermal.c b/drivers/thermal/intel_pch_thermal.c index 2b49e8d..9889c90 100644 --- a/drivers/thermal/intel_pch_thermal.c +++ b/drivers/thermal/intel_pch_thermal.c @@ -125,7 +125,7 @@ static int pch_wpt_init(struct pch_thermal_device *ptd, int *nr_trips) *nr_trips = 0; /* Check if BIOS has already enabled thermal sensor */ - if (WPT_TSS_TSDSS & readb(ptd->hw_base + WPT_TSS)) { + if (WPT_TSEL_ETS & readb(ptd->hw_base + WPT_TSEL)) { ptd->bios_enabled = true; goto read_trips; } @@ -141,7 +141,7 @@ static int pch_wpt_init(struct pch_thermal_device *ptd, int *nr_trips) } writeb(tsel|WPT_TSEL_ETS, ptd->hw_base + WPT_TSEL); - if (!(WPT_TSS_TSDSS & readb(ptd->hw_base + WPT_TSS))) { + if (!(WPT_TSEL_ETS & readb(ptd->hw_base + WPT_TSEL))) { dev_err(&ptd->pdev->dev, "Sensor can't be enabled\n"); return -ENODEV; } -- 1.9.1
[PATCH v5] Bluetooth: btusb: Fix memory leak in play_deferred
Currently we are calling usb_submit_urb directly to submit deferred tx urbs after unanchor them. So the usb_giveback_urb_bh would failed to unref it in usb_unanchor_urb and cause memory leak: unreferenced object 0xffc0ce0fa400 (size 256): ... backtrace: [] __save_stack_trace+0x48/0x6c [] create_object+0x138/0x254 [] kmemleak_alloc+0x58/0x8c [] __kmalloc+0x1d4/0x2a0 [] usb_alloc_urb+0x30/0x60 [] alloc_ctrl_urb+0x38/0x120 [btusb] [] btusb_send_frame+0x64/0xf8 [btusb] Put those urbs in tx_anchor to avoid the leak, and also fix the error handling. Signed-off-by: Jeffy Chen --- Changes in v5: Fix compile warning reported by "kbuild test robot": drivers/bluetooth/btusb.c:3288:3: warning: 'err' may be used uninitialized in this function [-Wmaybe-uninitialized] This 'err' would be set in the send loop, and would be used in the cleanup rest urb code outside the loop. Changes in v4: Drop the rest deferred urbs when error happens. Changes in v3: Put the deferred urbs in tx_anchor. Changes in v2: Call usb_free_urb instead of reusing submit_tx_urb. drivers/bluetooth/btusb.c | 23 --- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 0d533b2..91fdd60 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -3263,16 +3263,33 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) static void play_deferred(struct btusb_data *data) { struct urb *urb; - int err; + int err = 0; while ((urb = usb_get_from_anchor(&data->deferred))) { + usb_anchor_urb(urb, &data->tx_anchor); + err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) + if (err < 0) { + if (err != -EPERM && err != -ENODEV) + BT_ERR("%s urb %p submission failed (%d)", + data->hdev->name, urb, -err); + kfree(urb->setup_packet); + usb_unanchor_urb(urb); + usb_free_urb(urb); break; + } data->tx_in_flight++; + usb_free_urb(urb); + } + + /* Cleanup the rest deferred urbs. */ + while ((urb = usb_get_from_anchor(&data->deferred))) { + BT_ERR("%s urb %p submission failed (%d)", + data->hdev->name, urb, -err); + kfree(urb->setup_packet); + usb_free_urb(urb); } - usb_scuttle_anchored_urbs(&data->deferred); } static int btusb_resume(struct usb_interface *intf) -- 2.1.4
Re: [PATCH RESEND v4] MAINTAINERS: fix lots of alphabetic ordering
On Wed, Jul 19, 2017 at 5:26 PM, Linus Torvalds wrote: > On Wed, Jul 19, 2017 at 5:19 PM, Randy Dunlap wrote: >> >> Must be small and stupid. It applies cleanly for me. >> Do you have changes that are not pushed out publicly? > > Nope, my private tree matches the public one. Oh, I see it. Your mailer is crap, and destroys utf-8 characters. In particular: -M: MichaÅ‚ MirosÅ‚aw should be -M: Michał Mirosław I'm not sure what part of your flow is broken, because your mailer *claims* that it used Content-Type: text/plain; charset=utf-8 but it very much did not. When you attached that file, it did some odd character conversion crud. There may be other examples of this, but that's the one I see and the one that caused that to fail in that hunk. Linus
Re: [PATCH 1/3] ipc: convert ipc_namespace.count from atomic_t to refcount_t
On Wed, Jul 19, 2017 at 4:20 PM, Kees Cook wrote: > On Wed, Jul 19, 2017 at 4:11 PM, Davidlohr Bueso wrote: >> May I suggest using mmtests with the following config file: >> >> https://github.com/gormanm/mmtests/blob/7e070a810bc0af92e592e5121d0ea75fada51aeb/configs/config-global-dhp__workload-ipc-scale-short >> >> It will run two of Manfred's ipcscale sem benchmarks. > > I'll see if I can figure out how to use this for testing the fast > refcount protection: > https://lkml.org/lkml/2017/7/18/1223 > > Then we could see: > > before conversion > after conversion > with CONFIG_REFCOUNT_FULL > with fast refcount protection I have no idea how to read this report. It seems to be mostly noise (multiple baseline runs seem to show greater variability than compared against the other possible results). Test runs were atomic_t, atomic_t-2, refcount_t, refcount-full, and refcount-fast. (Two baselines, refcount_t conversion, with FULL, and with the fast implementation.) Output here: http://pastebin.ubuntu.com/25129382/ -Kees -- Kees Cook Pixel Security
[PATCH v2 1/7] driver core: emit uevents when device is bound to a driver
There are certain touch controllers that may come up in either normal (application) or boot mode, depending on whether firmware/configuration is corrupted when they are powered on. In boot mode the kernel does not create input device instance (because it does not necessarily know the characteristics of the input device in question). Another number of controllers does not store firmware in a non-volatile memory, and they similarly need to have firmware loaded before input device instance is created. There are also other types of devices with similar behavior. There is a desire to be able to trigger firmware loading via udev, but it has to happen only when driver is bound to a physical device (i2c or spi). These udev actions can not use ADD events, as those happen too early, so we are introducing BIND and UNBIND events that are emitted at the right moment. Also, many drivers create additional driver-specific device attributes when binding to the device, to provide userspace with additional controls. The new events allow userspace to adjust these driver-specific attributes without worrying that they are not there yet. Signed-off-by: Dmitry Torokhov --- drivers/base/dd.c | 4 include/linux/kobject.h | 2 ++ lib/kobject_uevent.c| 2 ++ 3 files changed, 8 insertions(+) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 4882f06d12df..c17fefc77345 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -259,6 +259,8 @@ static void driver_bound(struct device *dev) if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_BOUND_DRIVER, dev); + + kobject_uevent(&dev->kobj, KOBJ_BIND); } static int driver_sysfs_add(struct device *dev) @@ -848,6 +850,8 @@ static void __device_release_driver(struct device *dev, struct device *parent) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_UNBOUND_DRIVER, dev); + + kobject_uevent(&dev->kobj, KOBJ_UNBIND); } } diff --git a/include/linux/kobject.h b/include/linux/kobject.h index ca85cb80e99a..12f5ddccb97c 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -57,6 +57,8 @@ enum kobject_action { KOBJ_MOVE, KOBJ_ONLINE, KOBJ_OFFLINE, + KOBJ_BIND, + KOBJ_UNBIND, KOBJ_MAX }; diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 9a2b811966eb..4682e8545b5c 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -50,6 +50,8 @@ static const char *kobject_actions[] = { [KOBJ_MOVE] = "move", [KOBJ_ONLINE] = "online", [KOBJ_OFFLINE] ="offline", + [KOBJ_BIND] = "bind", + [KOBJ_UNBIND] = "unbind", }; /** -- 2.14.0.rc0.284.gd933b75aa4-goog
Re: [PATCH RESEND v4] MAINTAINERS: fix lots of alphabetic ordering
On Wed, Jul 19, 2017 at 5:19 PM, Randy Dunlap wrote: > > Must be small and stupid. It applies cleanly for me. > Do you have changes that are not pushed out publicly? Nope, my private tree matches the public one. The failure happens at the chunk for line 5086, fwiw. You don't seem to have used git to generate the patch, so it doesn't show the git blob ID's (which is a really nice way to show exactly which version of a file the diff was generated against). My current MAINTAINER file has git object ID 02994f42aacb07e79b9facf9881e3f0983929c0b Linus
[PATCH v2 3/7] driver core: add device_{add|remove}_group() helpers
We have helpers that work with NULL terminated array of groups, but many drivers only create a single supplemental group, and do not want to declare a group array. Let's provide them with helpers working with a single group. Signed-off-by: Dmitry Torokhov --- include/linux/device.h | 16 1 file changed, 16 insertions(+) diff --git a/include/linux/device.h b/include/linux/device.h index 10cf209a4e82..7698a513b35e 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1205,6 +1205,22 @@ extern int __must_check device_add_groups(struct device *dev, extern void device_remove_groups(struct device *dev, const struct attribute_group **groups); +static inline int __must_check device_add_group(struct device *dev, + const struct attribute_group *grp) +{ + const struct attribute_group *groups[] = { grp, NULL }; + + return device_add_groups(dev, groups); +} + +static inline void device_remove_group(struct device *dev, + const struct attribute_group *grp) +{ + const struct attribute_group *groups[] = { grp, NULL }; + + return device_remove_groups(dev, groups); +} + /* * Platform "fixup" functions - allow the platform to have their say * about devices and actions that the general device layer doesn't -- 2.14.0.rc0.284.gd933b75aa4-goog
[PATCH v2 6/7] Input: synaptics_rmi4 - use devm_device_add_group() for attributes in F01
Now that we have proper managed API to create device attributes, let's start using it instead of the manual unwinding. Signed-off-by: Dmitry Torokhov --- drivers/input/rmi4/rmi_f01.c | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c index aa1aabfdbe7c..ae966e333a2f 100644 --- a/drivers/input/rmi4/rmi_f01.c +++ b/drivers/input/rmi4/rmi_f01.c @@ -570,18 +570,14 @@ static int rmi_f01_probe(struct rmi_function *fn) dev_set_drvdata(&fn->dev, f01); - error = sysfs_create_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group); + error = devm_device_add_group(&fn->rmi_dev->dev, &rmi_f01_attr_group); if (error) - dev_warn(&fn->dev, "Failed to create sysfs group: %d\n", error); + dev_warn(&fn->dev, +"Failed to create attribute group: %d\n", error); return 0; } -static void rmi_f01_remove(struct rmi_function *fn) -{ - sysfs_remove_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group); -} - static int rmi_f01_config(struct rmi_function *fn) { struct f01_data *f01 = dev_get_drvdata(&fn->dev); @@ -721,7 +717,6 @@ struct rmi_function_handler rmi_f01_handler = { }, .func = 0x01, .probe = rmi_f01_probe, - .remove = rmi_f01_remove, .config = rmi_f01_config, .attention = rmi_f01_attention, .suspend= rmi_f01_suspend, -- 2.14.0.rc0.284.gd933b75aa4-goog
[PATCH v2 0/7] New bind/unbingd uevents
Hi Greg, Here is the v2 of bind/unbind uevent patch series. The new bind/unbind will allow triggering firmware update through udev, and the new device sysfs API will cut down on some boilerplate code in drivers. As you requested, I moved the new functions to device.h, in the process I exported existing device_add_groups() and device_remove_groups() and called the new functions devm_device_{add|remove}_group[s]() to get away from the sysfs "rawness". Below is also a patch to systemd to stop dropping the new attributes (why they think they need to inspect and discard the data they do not understand is beyond me). Thanks, Dmitry V2: - made device_{add|remove}_groups() public - added device_{add|remove}_group() helpers - the new devm APIs are moved into device.h and "sysfs" suffix dropped - added 3 patches showing use in the drivers V1: initial [re]post Dmitry Torokhov (7): driver core: emit uevents when device is bound to a driver driver core: make device_{add|remove}_groups() public driver core: add device_{add|remove}_group() helpers driver core: add devm_device_add_group() and friends Input: gpio_keys - use devm_device_add_group() for attributes Input: synaptics_rmi4 - use devm_device_add_group() for attributes in F01 Input: axp20x-pek - switch to using devm_device_add_group() drivers/base/base.h| 5 -- drivers/base/core.c| 132 + drivers/base/dd.c | 4 ++ drivers/input/keyboard/gpio_keys.c | 16 + drivers/input/misc/axp20x-pek.c| 18 + drivers/input/rmi4/rmi_f01.c | 11 +--- include/linux/device.h | 30 + include/linux/kobject.h| 2 + lib/kobject_uevent.c | 2 + 9 files changed, 176 insertions(+), 44 deletions(-) -- >8 -- >From 6d10e621578dffcca0ad785e4a73196aa25350f6 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 17 Jul 2017 20:10:17 -0700 Subject: [PATCH] Add handling for bind/unbind actions Newer kernels will emit uevents with "bind" and "unbind" actions. These uevents will be issued when driver is bound to or unbound from a device. "Bind" events are helpful when device requires a firmware to operate properly, and driver is unable to create a child device before firmware is properly loaded. For some reason systemd validates actions and drops the ones it does not know, instead of passing them on through as old udev did, so we need to explicitly teach it about them. --- src/libsystemd/sd-device/device-internal.h | 2 ++ src/libsystemd/sd-device/device-private.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/libsystemd/sd-device/device-internal.h b/src/libsystemd/sd-device/device-internal.h index f4783deef..0505a2730 100644 --- a/src/libsystemd/sd-device/device-internal.h +++ b/src/libsystemd/sd-device/device-internal.h @@ -104,6 +104,8 @@ typedef enum DeviceAction { DEVICE_ACTION_MOVE, DEVICE_ACTION_ONLINE, DEVICE_ACTION_OFFLINE, +DEVICE_ACTION_BIND, +DEVICE_ACTION_UNBIND, _DEVICE_ACTION_MAX, _DEVICE_ACTION_INVALID = -1, } DeviceAction; diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c index b4cd676c1..8839c3266 100644 --- a/src/libsystemd/sd-device/device-private.c +++ b/src/libsystemd/sd-device/device-private.c @@ -466,6 +466,8 @@ static const char* const device_action_table[_DEVICE_ACTION_MAX] = { [DEVICE_ACTION_MOVE] = "move", [DEVICE_ACTION_ONLINE] = "online", [DEVICE_ACTION_OFFLINE] = "offline", +[DEVICE_ACTION_BIND] = "bind", +[DEVICE_ACTION_UNBIND] = "unbind", }; DEFINE_STRING_TABLE_LOOKUP(device_action, DeviceAction);
[PATCH v2 2/7] driver core: make device_{add|remove}_groups() public
Many drivers create additional driver-specific device attributes when binding to the device. To avoid them calling SYSFS API directly, let's export these helpers. Signed-off-by: Dmitry Torokhov --- drivers/base/base.h| 5 - drivers/base/core.c| 2 ++ include/linux/device.h | 5 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index e19b1008e5fb..539432a14b5c 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -126,11 +126,6 @@ extern int driver_add_groups(struct device_driver *drv, extern void driver_remove_groups(struct device_driver *drv, const struct attribute_group **groups); -extern int device_add_groups(struct device *dev, -const struct attribute_group **groups); -extern void device_remove_groups(struct device *dev, -const struct attribute_group **groups); - extern char *make_class_name(const char *name, struct kobject *kobj); extern int devres_release_all(struct device *dev); diff --git a/drivers/base/core.c b/drivers/base/core.c index bbecaf9293be..14f8cf5c8b05 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1026,12 +1026,14 @@ int device_add_groups(struct device *dev, const struct attribute_group **groups) { return sysfs_create_groups(&dev->kobj, groups); } +EXPORT_SYMBOL_GPL(device_add_groups); void device_remove_groups(struct device *dev, const struct attribute_group **groups) { sysfs_remove_groups(&dev->kobj, groups); } +EXPORT_SYMBOL_GPL(device_remove_groups); static int device_add_attrs(struct device *dev) { diff --git a/include/linux/device.h b/include/linux/device.h index 9ef518af5515..10cf209a4e82 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1200,6 +1200,11 @@ struct device *device_create_with_groups(struct class *cls, const char *fmt, ...); extern void device_destroy(struct class *cls, dev_t devt); +extern int __must_check device_add_groups(struct device *dev, + const struct attribute_group **groups); +extern void device_remove_groups(struct device *dev, +const struct attribute_group **groups); + /* * Platform "fixup" functions - allow the platform to have their say * about devices and actions that the general device layer doesn't -- 2.14.0.rc0.284.gd933b75aa4-goog
[PATCH v2 7/7] Input: axp20x-pek - switch to using devm_device_add_group()
Now that we have proper managed API to create device attributes, let's use it instead of installing a custom devm action. Signed-off-by: Dmitry Torokhov --- drivers/input/misc/axp20x-pek.c | 18 +- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c index 38c79ebff033..cfeb0e943de6 100644 --- a/drivers/input/misc/axp20x-pek.c +++ b/drivers/input/misc/axp20x-pek.c @@ -182,13 +182,6 @@ static irqreturn_t axp20x_pek_irq(int irq, void *pwr) return IRQ_HANDLED; } -static void axp20x_remove_sysfs_group(void *_data) -{ - struct device *dev = _data; - - sysfs_remove_group(&dev->kobj, &axp20x_attribute_group); -} - static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek, struct platform_device *pdev) { @@ -313,22 +306,13 @@ static int axp20x_pek_probe(struct platform_device *pdev) return error; } - error = sysfs_create_group(&pdev->dev.kobj, &axp20x_attribute_group); + error = devm_device_add_group(&pdev->dev, &axp20x_attribute_group); if (error) { dev_err(&pdev->dev, "Failed to create sysfs attributes: %d\n", error); return error; } - error = devm_add_action(&pdev->dev, - axp20x_remove_sysfs_group, &pdev->dev); - if (error) { - axp20x_remove_sysfs_group(&pdev->dev); - dev_err(&pdev->dev, "Failed to add sysfs cleanup action: %d\n", - error); - return error; - } - platform_set_drvdata(pdev, axp20x_pek); return 0; -- 2.14.0.rc0.284.gd933b75aa4-goog
[PATCH v2 4/7] driver core: add devm_device_add_group() and friends
Many drivers create additional driver-specific device attributes when binding to the device, and providing managed version of device_create_group() will simplify unbinding and error handling in probe path for such drivers. Without managed version driver writers either have to mix manual and managed resources, which is prone to errors, or open-code this function by providing a wrapper to device_add_group() and use it with devm_add_action() or devm_add_action_or_reset(). Signed-off-by: Dmitry Torokhov --- drivers/base/core.c| 130 + include/linux/device.h | 9 2 files changed, 139 insertions(+) diff --git a/drivers/base/core.c b/drivers/base/core.c index 14f8cf5c8b05..09723532725d 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1035,6 +1035,136 @@ void device_remove_groups(struct device *dev, } EXPORT_SYMBOL_GPL(device_remove_groups); +union device_attr_group_devres { + const struct attribute_group *group; + const struct attribute_group **groups; +}; + +static int devm_attr_group_match(struct device *dev, void *res, void *data) +{ + return ((union device_attr_group_devres *)res)->group == data; +} + +static void devm_attr_group_remove(struct device *dev, void *res) +{ + union device_attr_group_devres *devres = res; + const struct attribute_group *group = devres->group; + + dev_dbg(dev, "%s: removing group %p\n", __func__, group); + sysfs_remove_group(&dev->kobj, group); +} + +static void devm_attr_groups_remove(struct device *dev, void *res) +{ + union device_attr_group_devres *devres = res; + const struct attribute_group **groups = devres->groups; + + dev_dbg(dev, "%s: removing groups %p\n", __func__, groups); + sysfs_remove_groups(&dev->kobj, groups); +} + +/** + * devm_device_add_group - given a device, create a managed attribute group + * @dev: The device to create the group for + * @grp: The attribute group to create + * + * This function creates a group for the first time. It will explicitly + * warn and error if any of the attribute files being created already exist. + * + * Returns 0 on success or error code on failure. + */ +int devm_device_add_group(struct device *dev, const struct attribute_group *grp) +{ + union device_attr_group_devres *devres; + int error; + + devres = devres_alloc(devm_attr_group_remove, + sizeof(*devres), GFP_KERNEL); + if (!devres) + return -ENOMEM; + + error = sysfs_create_group(&dev->kobj, grp); + if (error) { + devres_free(devres); + return error; + } + + devres->group = grp; + devres_add(dev, devres); + return 0; +} +EXPORT_SYMBOL_GPL(devm_device_add_group); + +/** + * devm_device_remove_group: remove a managed group from a device + * @dev: device to remove the group from + * @grp: group to remove + * + * This function removes a group of attributes from a device. The attributes + * previously have to have been created for this group, otherwise it will fail. + */ +void devm_device_remove_group(struct device *dev, + const struct attribute_group *grp) +{ + WARN_ON(devres_release(dev, devm_attr_group_remove, + devm_attr_group_match, + /* cast away const */ (void *)grp)); +} +EXPORT_SYMBOL_GPL(devm_device_remove_group); + +/** + * devm_device_add_groups - create a bunch of managed attribute groups + * @dev: The device to create the group for + * @groups:The attribute groups to create, NULL terminated + * + * This function creates a bunch of managed attribute groups. If an error + * occurs when creating a group, all previously created groups will be + * removed, unwinding everything back to the original state when this + * function was called. It will explicitly warn and error if any of the + * attribute files being created already exist. + * + * Returns 0 on success or error code from sysfs_create_group on failure. + */ +int devm_device_add_groups(struct device *dev, + const struct attribute_group **groups) +{ + union device_attr_group_devres *devres; + int error; + + devres = devres_alloc(devm_attr_groups_remove, + sizeof(*devres), GFP_KERNEL); + if (!devres) + return -ENOMEM; + + error = sysfs_create_groups(&dev->kobj, groups); + if (error) { + devres_free(devres); + return error; + } + + devres->groups = groups; + devres_add(dev, devres); + return 0; +} +EXPORT_SYMBOL_GPL(devm_device_add_groups); + +/** + * devm_device_remove_groups - remove a list of managed groups + * + * @dev: The device for the groups to be removed from + * @groups:NULL terminated list of groups to be removed + * + * If groups is not NULL,
[PATCH v2 5/7] Input: gpio_keys - use devm_device_add_group() for attributes
Now that we have proper managed API to create device attributes, let's start using it instead of the manual unwinding. Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/gpio_keys.c | 16 ++-- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index f52812db91bc..e9f0ebf3267a 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -827,7 +827,7 @@ static int gpio_keys_probe(struct platform_device *pdev) fwnode_handle_put(child); - error = sysfs_create_group(&dev->kobj, &gpio_keys_attr_group); + error = devm_device_add_group(dev, &gpio_keys_attr_group); if (error) { dev_err(dev, "Unable to export keys/switches, error: %d\n", error); @@ -838,22 +838,11 @@ static int gpio_keys_probe(struct platform_device *pdev) if (error) { dev_err(dev, "Unable to register input device, error: %d\n", error); - goto err_remove_group; + return error; } device_init_wakeup(dev, wakeup); - return 0; - -err_remove_group: - sysfs_remove_group(&dev->kobj, &gpio_keys_attr_group); - return error; -} - -static int gpio_keys_remove(struct platform_device *pdev) -{ - sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); - return 0; } @@ -912,7 +901,6 @@ static SIMPLE_DEV_PM_OPS(gpio_keys_pm_ops, gpio_keys_suspend, gpio_keys_resume); static struct platform_driver gpio_keys_device_driver = { .probe = gpio_keys_probe, - .remove = gpio_keys_remove, .driver = { .name = "gpio-keys", .pm = &gpio_keys_pm_ops, -- 2.14.0.rc0.284.gd933b75aa4-goog
Re: [PATCH v3 04/15] selinux: Refactor to remove bprm_secureexec hook
On Wed, Jul 19, 2017 at 8:03 PM, Paul Moore wrote: > On Tue, Jul 18, 2017 at 6:25 PM, Kees Cook wrote: >> The SELinux bprm_secureexec hook can be merged with the bprm_set_creds >> hook since it's dealing with the same information, and all of the details >> are finalized during the first call to the bprm_set_creds hook via >> prepare_binprm() (subsequent calls due to binfmt_script, etc, are ignored >> via bprm->called_set_creds). >> >> Here, the test can just happen at the end of the bprm_set_creds hook, >> and the bprm_secureexec hook can be dropped. >> >> Cc: Paul Moore >> Cc: Stephen Smalley >> Signed-off-by: Kees Cook >> --- >> security/selinux/hooks.c | 24 +--- >> 1 file changed, 5 insertions(+), 19 deletions(-) > > This seems reasonable in the context of the other changes. > > Stephen just posted an AT_SECURE test for the selinux-testsuite on the > SELinux mailing list, it would be nice to ensure that this patchset > doesn't run afoul of that. Quick follow-up: I just merged Stephen's test into the test suite: * https://github.com/SELinuxProject/selinux-testsuite > Acked-by: Paul Moore > >> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c >> index 0f1450a06b02..18038f73a2f7 100644 >> --- a/security/selinux/hooks.c >> +++ b/security/selinux/hooks.c >> @@ -2413,30 +2413,17 @@ static int selinux_bprm_set_creds(struct >> linux_binprm *bprm) >> >> /* Clear any possibly unsafe personality bits on exec: */ >> bprm->per_clear |= PER_CLEAR_ON_SETID; >> - } >> - >> - return 0; >> -} >> - >> -static int selinux_bprm_secureexec(struct linux_binprm *bprm) >> -{ >> - const struct task_security_struct *tsec = current_security(); >> - u32 sid, osid; >> - int atsecure = 0; >> - >> - sid = tsec->sid; >> - osid = tsec->osid; >> >> - if (osid != sid) { >> /* Enable secure mode for SIDs transitions unless >>the noatsecure permission is granted between >>the two SIDs, i.e. ahp returns 0. */ >> - atsecure = avc_has_perm(osid, sid, >> - SECCLASS_PROCESS, >> - PROCESS__NOATSECURE, NULL); >> + rc = avc_has_perm(old_tsec->sid, new_tsec->sid, >> + SECCLASS_PROCESS, PROCESS__NOATSECURE, >> + NULL); >> + bprm->secureexec |= !!rc; >> } >> >> - return !!atsecure; >> + return 0; >> } >> >> static int match_file(const void *p, struct file *file, unsigned fd) >> @@ -6151,7 +6138,6 @@ static struct security_hook_list selinux_hooks[] >> __lsm_ro_after_init = { >> LSM_HOOK_INIT(bprm_set_creds, selinux_bprm_set_creds), >> LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds), >> LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), >> - LSM_HOOK_INIT(bprm_secureexec, selinux_bprm_secureexec), >> >> LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), >> LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), >> -- >> 2.7.4 > > -- > paul moore > www.paul-moore.com -- paul moore www.paul-moore.com
Re: [PATCH RESEND v4] MAINTAINERS: fix lots of alphabetic ordering
On 07/19/2017 05:08 PM, Linus Torvalds wrote: > On Wed, Jul 19, 2017 at 2:44 PM, Andrew Morton > wrote: >> >> Linus, can you please grab this? > > Ugh. It doesn't apply cleanly. Probably for some really small stupid reason. Must be small and stupid. It applies cleanly for me. Do you have changes that are not pushed out publicly? > I can easily just look at the reject and fix it, but I don't really > want to. Why? Because I hate the MAINTAINERS file. -- ~Randy
Re: [PATCH RESEND v4] MAINTAINERS: fix lots of alphabetic ordering
On 07/19/2017 05:08 PM, Linus Torvalds wrote: > On Wed, Jul 19, 2017 at 2:44 PM, Andrew Morton > wrote: >> >> Linus, can you please grab this? > > Ugh. It doesn't apply cleanly. Probably for some really small stupid reason. > > I can easily just look at the reject and fix it, but I don't really > want to. Why? Because I hate the MAINTAINERS file. > > It's the most painful file for merging too, because everybody touches > it - kind of like the old "one single Kconfig file" was back in the > bad old days. > > For example, just during this merge window: > > $ git rev-list --count --no-merges v4.12.. MAINTAINERS > 112 > > and while most of them obviously didn't cause any conflicts (there > were four this cycle), it's still my least favourite "stupid work". > That file pretty consistently gets 100+ changes to it: > > v4.1: 87 > v4.2: 109 > v4.3: 94 > v4.4: 91 > v4.5: 118 > v4.6: 98 > v4.7: 112 > v4.8: 121 > v4.9: 128 > v4.10: 135 > v4.11: 78 > v4.12: 127 > > So I'm wondering if > > (a) we could add a script to do the alphabetical ordering properly. Yeah, I have already thought about that one. I may get around tuit one day. Or maybe Joe could/would. > (b) we could split this thing up some sane way. makes sense. > Anybody got any ideas? (c) funnel all changes thru Andrew (but really foo should be able to make changes to her MAINTAINERS entry) > I'm throwing out _one_ idea: split it up by the main F: line, so that > maintainership information ends up being hierarchical like the Kconfig > files. Teach "get_maintainer.pl" to just do "find . -name > MAINTAINERS" instead? > > I'm not saying that's a great idea (quite often the "main F: line" > might be ambiguous), but it's the most obvious one. > > This is not a _huge_ problem, but it has been a slight annoyance for a > long time now. So it would be good to maybe at least discuss it a bit. -- ~Randy
Re: [PATCH RESEND v4] MAINTAINERS: fix lots of alphabetic ordering
On Wed, Jul 19, 2017 at 5:08 PM, Linus Torvalds wrote: > > I'm throwing out _one_ idea: split it up by the main F: line, so that > maintainership information ends up being hierarchical like the Kconfig > files. Teach "get_maintainer.pl" to just do "find . -name > MAINTAINERS" instead? For a more radical change, get rid of the MAINTAINERS file entirely, and put the information into the Kconfig files - kind of like the "help" text, except with the rules. It's probably not really workable, but in many ways the maintainership often tends to more closely match the configuration than the tree layout, and some of the fields would actually make sense for the help thing (eg the whole support status, but also the web-page with status/info pointer). Again - just throwing this out as a "please discuss" thing. Linus
Re: [RFC 06/22] kvm: Adapt assembly for PIE support
,Chris Metcalf ,"Paul E . McKenney" ,Andrew Morton ,Christopher Li ,Dou Liyang ,Masahiro Yamada ,Daniel Borkmann ,Markus Trippelsdorf ,Peter Foley ,Steven Rostedt ,Tim Chen ,Catalin Marinas ,Matthew Wilcox ,Michal Hocko ,Rob Landley ,Jiri Kosina ,"H . J . Lu" ,Paul Bolle ,Baoquan He ,Daniel Micay ,the arch/x86 maintainers ,"linux-cry...@vger.kernel.org" ,Linux Kernel Mailing List ,xen-de...@lists.xenproject.org,kvm list ,linux-pm ,linux-arch ,Linux-Sparse ,Kernel Hardening From: h...@zytor.com Message-ID: <83ba7600-bc8d-4c91-812c-dd2a0bf44...@zytor.com> On July 19, 2017 3:58:07 PM PDT, Ard Biesheuvel wrote: >On 19 July 2017 at 23:27, H. Peter Anvin wrote: >> On 07/19/17 08:40, Thomas Garnier wrote: This doesn't look right. It's accessing a per-cpu variable. The per-cpu section is an absolute, zero-based section and not subject >to relocation. >>> >>> PIE does not respect the zero-based section, it tries to have >>> everything relative. Patch 16/22 also adapt per-cpu to work with PIE >>> (while keeping the zero absolute design by default). >>> >> >> This is silly. The right thing is for PIE is to be explicitly >absolute, >> without (%rip). The use of (%rip) memory references for percpu is >just >> an optimization. >> > >Sadly, there is an issue in binutils that may prevent us from doing >this as cleanly as we would want. > >For historical reasons, bfd.ld emits special symbols like >__GLOBAL_OFFSET_TABLE__ as absolute symbols with a section index of >SHN_ABS, even though it is quite obvious that they are relative like >any other symbol that points into the image. Unfortunately, this means >that binutils needs to emit R_X86_64_RELATIVE relocations even for >SHN_ABS symbols, which means we lose the ability to use both absolute >and relocatable symbols in the same PIE image (unless the reloc tool >can filter them out) > >More info here: >https://sourceware.org/bugzilla/show_bug.cgi?id=19818 The reloc tool already has the ability to filter symbols. -- Sent from my Android device with K-9 Mail. Please excuse my brevity.
Re: [RFC 20/22] x86/relocs: Add option to generate 64-bit relocations
,"Paul E . McKenney" ,Andrew Morton ,Christopher Li ,Dou Liyang ,Masahiro Yamada ,Daniel Borkmann ,Markus Trippelsdorf ,Peter Foley ,Steven Rostedt ,Tim Chen ,Ard Biesheuvel ,Catalin Marinas ,Matthew Wilcox ,Michal Hocko ,Rob Landley ,Jiri Kosina ,"H . J . Lu" ,Paul Bolle ,Baoquan He ,Daniel Micay ,the arch/x86 maintainers ,linux-cry...@vger.kernel.org,LKML ,xen-de...@lists.xenproject.org,kvm list ,Linux PM list ,linux-arch ,linux-spa...@vger.kernel.org,Kernel Hardening From: h...@zytor.com Message-ID: <0ef6faaa-a99c-4f0d-9e4a-ad25e9395...@zytor.com> On July 19, 2017 4:25:56 PM PDT, Thomas Garnier wrote: >On Wed, Jul 19, 2017 at 4:08 PM, H. Peter Anvin wrote: >> On 07/19/17 15:47, Thomas Garnier wrote: >>> On Wed, Jul 19, 2017 at 3:33 PM, H. Peter Anvin >wrote: On 07/18/17 15:33, Thomas Garnier wrote: > The x86 relocation tool generates a list of 32-bit signed >integers. There > was no need to use 64-bit integers because all addresses where >above the 2G > top of the memory. > > This change add a large-reloc option to generate 64-bit unsigned >integers. > It can be used when the kernel plan to go below the top 2G and >32-bit > integers are not enough. Why on Earth? This would only be necessary if the *kernel itself* >was more than 2G, which isn't going to happen for the forseeable >future. >>> >>> Because the relocation integer is an absolute address, not an offset >>> in the binary. Next iteration, I can try using a 32-bit offset for >>> everyone. >> >> It is an absolute address *as the kernel was originally linked*, for >> obvious reasons. > >Sure when the kernel was just above 0x8000, it doesn't >work when it goes down to 0x. That's why using an >offset might make more sense in general. > >> >> -hpa >> What is the motivation for changing the pre linked address at all? -- Sent from my Android device with K-9 Mail. Please excuse my brevity.
[PATCH] sparc64: Register hugepages during arch init
Add hstate for each supported hugepage size using arch initcall. This change fixes some hugepage parameter parsing inconsistencies: case 1: no hugepage parameters Without hugepage parameters, only a hugepages-8192kB entry is visible in sysfs. It's different from x86_64 where both 2M and 1G hugepage sizes are available. case 2: default_hugepagesz=[64K|256M|2G] When specifying only a default_hugepagesz parameter, the default hugepage size isn't really changed and it stays at 8M. This is again different from x86_64. Orabug: 25869946 Reviewed-by: Bob Picco Signed-off-by: Nitin Gupta --- arch/sparc/mm/init_64.c | 25 - 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 3c40ebd..fed73f1 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -325,6 +325,29 @@ static void __update_mmu_tsb_insert(struct mm_struct *mm, unsigned long tsb_inde } #ifdef CONFIG_HUGETLB_PAGE +static void __init add_huge_page_size(unsigned long size) +{ + unsigned int order; + + if (size_to_hstate(size)) + return; + + order = ilog2(size) - PAGE_SHIFT; + hugetlb_add_hstate(order); +} + +static int __init hugetlbpage_init(void) +{ + add_huge_page_size(1UL << HPAGE_64K_SHIFT); + add_huge_page_size(1UL << HPAGE_SHIFT); + add_huge_page_size(1UL << HPAGE_256MB_SHIFT); + add_huge_page_size(1UL << HPAGE_2GB_SHIFT); + + return 0; +} + +arch_initcall(hugetlbpage_init); + static int __init setup_hugepagesz(char *string) { unsigned long long hugepage_size; @@ -364,7 +387,7 @@ static int __init setup_hugepagesz(char *string) goto out; } - hugetlb_add_hstate(hugepage_shift - PAGE_SHIFT); + add_huge_page_size(hugepage_size); rc = 1; out: -- 2.9.2
Re: [PATCH RESEND v4] MAINTAINERS: fix lots of alphabetic ordering
On Wed, Jul 19, 2017 at 2:44 PM, Andrew Morton wrote: > > Linus, can you please grab this? Ugh. It doesn't apply cleanly. Probably for some really small stupid reason. I can easily just look at the reject and fix it, but I don't really want to. Why? Because I hate the MAINTAINERS file. It's the most painful file for merging too, because everybody touches it - kind of like the old "one single Kconfig file" was back in the bad old days. For example, just during this merge window: $ git rev-list --count --no-merges v4.12.. MAINTAINERS 112 and while most of them obviously didn't cause any conflicts (there were four this cycle), it's still my least favourite "stupid work". That file pretty consistently gets 100+ changes to it: v4.1: 87 v4.2: 109 v4.3: 94 v4.4: 91 v4.5: 118 v4.6: 98 v4.7: 112 v4.8: 121 v4.9: 128 v4.10: 135 v4.11: 78 v4.12: 127 So I'm wondering if (a) we could add a script to do the alphabetical ordering properly. (b) we could split this thing up some sane way. Anybody got any ideas? I'm throwing out _one_ idea: split it up by the main F: line, so that maintainership information ends up being hierarchical like the Kconfig files. Teach "get_maintainer.pl" to just do "find . -name MAINTAINERS" instead? I'm not saying that's a great idea (quite often the "main F: line" might be ambiguous), but it's the most obvious one. This is not a _huge_ problem, but it has been a slight annoyance for a long time now. So it would be good to maybe at least discuss it a bit. Hmm? Linus
Re: commit 16ecba59 breaks 82574L under heavy load.
On 2017/07/19 10:19, Lennart Sorensen wrote: > On Tue, Jul 18, 2017 at 04:14:35PM -0700, Benjamin Poirier wrote: > > Thanks for the detailed analysis. > > > > Refering to the original discussion around this patch series, it seemed like > > the IMS bit for a condition had to be set for the Other interrupt to be > > raised > > for that condition. > > > > https://lkml.org/lkml/2015/11/4/683 > > > > In this case however, E1000_ICR_RXT0 is not set in IMS so Other shouldn't be > > raised for Receiver Overrun. Apparently something is going on... > > > > I can reproduce the spurious Other interrupts with a simple mdelay() > > With the debugging patch at the end of the mail I see stuff like this > > while blasting with udp frames: > > -0 [086] d.h1 15338.742675: e1000_msix_other: got Other > > interrupt, count 15127 > ><...>-54504 [086] d.h. 15338.742724: e1000_msix_other: got Other > > interrupt, count 1 > ><...>-54504 [086] d.h. 15338.742774: e1000_msix_other: got Other > > interrupt, count 1 > ><...>-54504 [086] d.h. 15338.742824: e1000_msix_other: got Other > > interrupt, count 1 > > -0 [086] d.h1 15340.745123: e1000_msix_other: got Other > > interrupt, count 27584 > ><...>-54504 [086] d.h. 15340.745172: e1000_msix_other: got Other > > interrupt, count 1 > ><...>-54504 [086] d.h. 15340.745222: e1000_msix_other: got Other > > interrupt, count 1 > ><...>-54504 [086] d.h. 15340.745272: e1000_msix_other: got Other > > interrupt, count 1 > > > > > hence sets the flag that (unfortunately) means both link is down and link > > > state should be checked. Since this now happens 3000 times per second, > > > the chances of it happening while the watchdog_task is checking the link > > > state becomes pretty high, and it if does happen to coincice, then the > > > watchdog_task will reset the adapter, which causes a real loss of link. > > > > Through which path does watchdog_task reset the adapter? I didn't > > reproduce that. > > The other interrupt happens and sets get_link_status to true. At some > point the watchdog_task runs on some core and calls e1000e_has_link, > which then calls check_for_link to find out the current link status. > While e1000e_check_for_copper_link is checking the link state and > after updating get_link_status to false to indicate link is up, another > interrupt occurs and another core handles it and changes get_link_status > to true again. So by the time e1000e_has_link goes to determine the > return value, get_link_state has changed back again so now it returns > link down, and as a result the watchdog_task calls reset, because we > have packets in the transmit queue (we were busy forwarding over 10 > packets per second when it happened). Ah I see. Thanks again. In your previous mail, On 2017/07/18 10:21, Lennart Sorensen wrote: [...] > I tried checking what the bits in the ICR actually were under these > conditions, and it would appear that the only bit set is 24 (the Other > Causes interrupt bit). So I don't know what the real cause is although Are you sure about this? In my testing, while triggering the overrun with the msleep, I read ICR when entering e1000_msix_other() and RXO is consistently set. I'm working on a patch that uses that fact to handle the situation and limit the interrupt.
Re: [PATCH] scsi: mpt3sas_scsih: remove unnecessary statics
On Wed, 2017-07-19 at 17:06 -0500, Gustavo A. R. Silva wrote: > Remove unnecessary static on local variables raid_device. > Such variables are initialized before being used, on > every execution path throughout the functions. The > static has no benefit and, removing it reduces the > object file size. > > This issue was detected using Coccinelle and the following semantic > patch: > > @bad exists@ > position p; > identifier x; > type T; > @@ > > static T x@p; > ... > x = <+...x...+> > > @@ > identifier x; > expression e; > type T; > position p != bad.p; > @@ > > -static > T x@p; > ... when != x > when strict > ?x = e; > > In the following log you can see a significant difference in the > object file size. This log is the output of the size command, before > and after the code change: > > before: > textdata bss dec hex filename > 126304 303841280 157968 26910 > drivers/scsi/mpt3sas/mpt3sas_scsih.o > > after: > textdata bss dec hex filename > 126292 302401152 157684 267f4 > drivers/scsi/mpt3sas/mpt3sas_scsih.o I've got to say I'm deeply uneasy about using a data/bss size reduction as the benchmark for saying something shouldn't be declared static. In this particular case the reduction is minimal, so it probably doesn't matter; however, if the reduction were more significant, changing from static to dynamic (i.e. on stack) allocation would increase the risk that we'd blow the kernel stack. Indeed one reason you might find static declarations in functions is precisely to avoid blowing the stack, so we wouldn't want to reverse them. Other reasons for having static allocations instead of dynamic ones is that you need to DMA to/from the structure (you can't DMA to stack) or because you want to preserve values across function invocations. There are definite reasons why statics in functions are a bad idea: they prevent recursion and trip up code analysis, but in none of the above cases would the fix be to remove the static qualifier. James
Re: linux-next: Tree for Jul 19 (drivers/sfi)
On 07/18/2017 09:54 PM, Stephen Rothwell wrote: > Hi all, > > Changes since 20170718: > on i386: ../drivers/sfi/sfi_core.c: In function 'sfi_map_memory': ../drivers/sfi/sfi_core.c:104:3: error: implicit declaration of function 'memremap' [-Werror=implicit-function-declaration] return memremap(phys, size, MEMREMAP_WB); ^ ../drivers/sfi/sfi_core.c:104:31: error: 'MEMREMAP_WB' undeclared (first use in this function) return memremap(phys, size, MEMREMAP_WB); ^ ../drivers/sfi/sfi_core.c:104:31: note: each undeclared identifier is reported only once for each function it appears in ../drivers/sfi/sfi_core.c: In function 'sfi_unmap_memory': ../drivers/sfi/sfi_core.c:115:3: error: implicit declaration of function 'memunmap' [-Werror=implicit-function-declaration] memunmap(virt); ^ ../drivers/sfi/sfi_core.c: In function 'sfi_map_memory': ../drivers/sfi/sfi_core.c:107:1: warning: control reaches end of non-void function [-Wreturn-type] } ^ -- ~Randy
Re: [PATCH v3 04/15] selinux: Refactor to remove bprm_secureexec hook
On Tue, Jul 18, 2017 at 6:25 PM, Kees Cook wrote: > The SELinux bprm_secureexec hook can be merged with the bprm_set_creds > hook since it's dealing with the same information, and all of the details > are finalized during the first call to the bprm_set_creds hook via > prepare_binprm() (subsequent calls due to binfmt_script, etc, are ignored > via bprm->called_set_creds). > > Here, the test can just happen at the end of the bprm_set_creds hook, > and the bprm_secureexec hook can be dropped. > > Cc: Paul Moore > Cc: Stephen Smalley > Signed-off-by: Kees Cook > --- > security/selinux/hooks.c | 24 +--- > 1 file changed, 5 insertions(+), 19 deletions(-) This seems reasonable in the context of the other changes. Stephen just posted an AT_SECURE test for the selinux-testsuite on the SELinux mailing list, it would be nice to ensure that this patchset doesn't run afoul of that. Acked-by: Paul Moore > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c > index 0f1450a06b02..18038f73a2f7 100644 > --- a/security/selinux/hooks.c > +++ b/security/selinux/hooks.c > @@ -2413,30 +2413,17 @@ static int selinux_bprm_set_creds(struct linux_binprm > *bprm) > > /* Clear any possibly unsafe personality bits on exec: */ > bprm->per_clear |= PER_CLEAR_ON_SETID; > - } > - > - return 0; > -} > - > -static int selinux_bprm_secureexec(struct linux_binprm *bprm) > -{ > - const struct task_security_struct *tsec = current_security(); > - u32 sid, osid; > - int atsecure = 0; > - > - sid = tsec->sid; > - osid = tsec->osid; > > - if (osid != sid) { > /* Enable secure mode for SIDs transitions unless >the noatsecure permission is granted between >the two SIDs, i.e. ahp returns 0. */ > - atsecure = avc_has_perm(osid, sid, > - SECCLASS_PROCESS, > - PROCESS__NOATSECURE, NULL); > + rc = avc_has_perm(old_tsec->sid, new_tsec->sid, > + SECCLASS_PROCESS, PROCESS__NOATSECURE, > + NULL); > + bprm->secureexec |= !!rc; > } > > - return !!atsecure; > + return 0; > } > > static int match_file(const void *p, struct file *file, unsigned fd) > @@ -6151,7 +6138,6 @@ static struct security_hook_list selinux_hooks[] > __lsm_ro_after_init = { > LSM_HOOK_INIT(bprm_set_creds, selinux_bprm_set_creds), > LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds), > LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), > - LSM_HOOK_INIT(bprm_secureexec, selinux_bprm_secureexec), > > LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), > LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), > -- > 2.7.4 -- paul moore www.paul-moore.com
Re: [PATCH] ARM: dts: bcm283x: Move the BCM2837 DT contents from arm64 to arm.
Hi Eric, suggestion inline On 17-07-19 01:19 PM, Eric Anholt wrote: BCM2837 is somewhat unusual in that we build its DT on both arm32 and arm64. Most devices are being run in arm32 mode. Having the body of the DT for 2837 separate from 2835/6 has been a source of pain, as we often need to make changes that span both directories simultaneously (for example, the thermal changes for 4.13, and pinmuxing changes earlier). Other changes are made more complicated than they need to be, such as the SDHOST enabling, because we end up splitting a single change into a 283[56] half and a 2837 half. Signed-off-by: Eric Anholt --- I had asked about what we could do about our DT merging troubles back in https://lkml.org/lkml/2017/5/16/707 with no response. I'm hoping we can take this patch as a resolution to that, and submit (almost all) future RPi DT changes through the arm32 dt tree. arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 42 +- .../dts/broadcom => arm/boot/dts}/bcm2837.dtsi | 0 arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts | 42 +- 3 files changed, 42 insertions(+), 42 deletions(-) rename arch/{arm64/boot/dts/broadcom => arm/boot/dts}/bcm2837.dtsi (100%) diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts index c72a27d908b6..972f14db28ac 100644 --- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts @@ -1 +1,41 @@ -#include "arm64/broadcom/bcm2837-rpi-3-b.dts" +/dts-v1/; +#include "bcm2837.dtsi" +#include "bcm2835-rpi.dtsi" +#include "bcm283x-rpi-smsc9514.dtsi" +#include "bcm283x-rpi-usb-host.dtsi" If you're moving this back to the arm directory why not change the include path and remove the 4 symlinks in arm64/boot/dts/broadcom? +#include "arm/bcm2837.dtsi" +#include "arm/bcm2835-rpi.dtsi" +#include "arm/bcm283x-rpi-smsc9514.dtsi" +#include "arm/bcm283x-rpi-usb-host.dtsi" + +/ { + compatible = "raspberrypi,3-model-b", "brcm,bcm2837"; + model = "Raspberry Pi 3 Model B"; + + memory { + reg = <0 0x4000>; + }; + + leds { + act { + gpios = <&gpio 47 0>; + }; + }; +}; + +&uart1 { + status = "okay"; +}; + +/* SDHCI is used to control the SDIO for wireless */ +&sdhci { + pinctrl-names = "default"; + pinctrl-0 = <&emmc_gpio34>; + status = "okay"; + bus-width = <4>; + non-removable; +}; + +/* SDHOST is used to drive the SD card */ +&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + status = "okay"; + bus-width = <4>; +}; diff --git a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi b/arch/arm/boot/dts/bcm2837.dtsi similarity index 100% rename from arch/arm64/boot/dts/broadcom/bcm2837.dtsi rename to arch/arm/boot/dts/bcm2837.dtsi diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts index 972f14db28ac..699d340a3437 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts +++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts @@ -1,41 +1 @@ -/dts-v1/; -#include "bcm2837.dtsi" -#include "bcm2835-rpi.dtsi" -#include "bcm283x-rpi-smsc9514.dtsi" -#include "bcm283x-rpi-usb-host.dtsi" - -/ { - compatible = "raspberrypi,3-model-b", "brcm,bcm2837"; - model = "Raspberry Pi 3 Model B"; - - memory { - reg = <0 0x4000>; - }; - - leds { - act { - gpios = <&gpio 47 0>; - }; - }; -}; - -&uart1 { - status = "okay"; -}; - -/* SDHCI is used to control the SDIO for wireless */ -&sdhci { - pinctrl-names = "default"; - pinctrl-0 = <&emmc_gpio34>; - status = "okay"; - bus-width = <4>; - non-removable; -}; - -/* SDHOST is used to drive the SD card */ -&sdhost { - pinctrl-names = "default"; - pinctrl-0 = <&sdhost_gpio48>; - status = "okay"; - bus-width = <4>; -}; +#include "arm/bcm2837-rpi-3-b.dts"
[PATCH -next] staging: pi433: depends on SPI
From: Randy Dunlap The pi433 driver uses SPI interfaces so it should depend on SPI. Also, the "default n" can be removed since that is already the default. Fixes these build errors when SPI is not enabled: drivers/staging/pi433/pi433_if.o: In function `pi433_probe': pi433_if.c:(.text+0x1135): undefined reference to `spi_setup' pi433_if.c:(.text+0x1177): undefined reference to `spi_write_then_read' drivers/staging/pi433/pi433_if.o: In function `pi433_init': pi433_if.c:(.init.text+0xb8): undefined reference to `__spi_register_driver' drivers/staging/pi433/rf69.o: In function `rf69_read_fifo': rf69.c:(.text+0x102): undefined reference to `spi_sync' drivers/staging/pi433/rf69.o: In function `rf69_write_fifo': rf69.c:(.text+0x248): undefined reference to `spi_sync' drivers/staging/pi433/rf69.o: In function `rf69_read_reg': rf69.c:(.text+0x290): undefined reference to `spi_write_then_read' drivers/staging/pi433/rf69.o: In function `rf69_write_reg': rf69.c:(.text+0x523): undefined reference to `spi_sync' Signed-off-by: Randy Dunlap Cc: Marcus Wolf --- drivers/staging/pi433/Kconfig |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- next-2017-0719.orig/drivers/staging/pi433/Kconfig +++ next-2017-0719/drivers/staging/pi433/Kconfig @@ -1,6 +1,6 @@ config PI433 tristate "Pi433 - a 433MHz radio module for Raspberry Pi" -default n +depends on SPI ---help--- This option allows you to enable support for the radio module Pi433.
Re: [PATCH v3 02/15] exec: Rename bprm->cred_prepared to called_set_creds
On Tue, Jul 18, 2017 at 6:25 PM, Kees Cook wrote: > The cred_prepared bprm flag has a misleading name. It has nothing to do > with the bprm_prepare_cred hook, and actually tracks if bprm_set_creds has > been called. Rename this flag and improve its comment. > > Cc: David Howells > Cc: John Johansen > Cc: Paul Moore > Cc: Stephen Smalley > Cc: Casey Schaufler > Cc: James Morris > Signed-off-by: Kees Cook > --- > fs/binfmt_flat.c | 2 +- > fs/exec.c | 2 +- > include/linux/binfmts.h| 8 ++-- > security/apparmor/domain.c | 2 +- > security/selinux/hooks.c | 2 +- > security/smack/smack_lsm.c | 2 +- > security/tomoyo/tomoyo.c | 2 +- > 7 files changed, 12 insertions(+), 8 deletions(-) Acked-by: Paul Moore -- paul moore www.paul-moore.com
Re: [PATCH 3.18 00/28] 3.18.62-stable review
On 07/19/2017 05:15 AM, Greg Kroah-Hartman wrote: > This is the start of the stable review cycle for the 3.18.62 release. > There are 28 patches in this series, all will be posted as a response > to this one. If anyone has any issues with these being applied, please > let me know. > > Responses should be made by Fri Jul 21 11:13:09 UTC 2017. > Anything received after that time might be too late. > > The whole patch series can be found in one patch at: > kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.18.62-rc1.gz > or in the git tree and branch at: > git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git > linux-3.18.y > and the diffstat can be found below. > > thanks, > > greg k-h > Compiled and booted on my test system. No dmesg regressions. thanks, -- Shuah
Re: [PATCH 4.4 00/57] 4.4.78-stable review
On 07/19/2017 05:12 AM, Greg Kroah-Hartman wrote: > This is the start of the stable review cycle for the 4.4.78 release. > There are 57 patches in this series, all will be posted as a response > to this one. If anyone has any issues with these being applied, please > let me know. > > Responses should be made by Fri Jul 21 11:12:31 UTC 2017. > Anything received after that time might be too late. > > The whole patch series can be found in one patch at: > kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.78-rc1.gz > or in the git tree and branch at: > git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git > linux-4.4.y > and the diffstat can be found below. > > thanks, > > greg k-h > Compiled and booted on my test system. No dmesg regressions. thanks, -- Shuah