All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 1/5] clk: Add clock driver for ASPEED BMC SoCs
From: Andrew Jeffery @ 2017-10-05  6:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171003065540.11722-2-joel@jms.id.au>

On Tue, 2017-10-03 at 17:25 +1030, Joel Stanley wrote:
> This adds the stub of a driver for the ASPEED SoCs. The clocks are
> defined and the static registration is set up.
>?
> Signed-off-by: Joel Stanley <joel@jms.id.au>

With respect to use of the Aspeed hardware,

Reviewed-by: Andrew Jeffery <andrew@aj.id.au>

> ---
> v3:
> ?- use named initlisers for aspeed_gates table
> ?- fix clocks typo
> ?- Move ASPEED_NUM_CLKS to the bottom of the list
> ?- Put gates at the start of the list, so we can use them to initalise
> ???the aspeed_gates table
> ?- Add ASPEED_CLK_SELECTION_2
> ?- Set parent of network MAC gates
> ---
> ?drivers/clk/Kconfig??????????????????????|??12 +++
> ?drivers/clk/Makefile?????????????????????|???1 +
> ?drivers/clk/clk-aspeed.c?????????????????| 148 +++++++++++++++++++++++++++++++
> ?include/dt-bindings/clock/aspeed-clock.h |??42 +++++++++
> ?4 files changed, 203 insertions(+)
> ?create mode 100644 drivers/clk/clk-aspeed.c
> ?create mode 100644 include/dt-bindings/clock/aspeed-clock.h
>?
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index 1c4e1aa6767e..9abe063ef8d2 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -142,6 +142,18 @@ config COMMON_CLK_GEMINI
> ?	??This driver supports the SoC clocks on the Cortina Systems Gemini
> ?	??platform, also known as SL3516 or CS3516.
> ?
> +config COMMON_CLK_ASPEED
> +	bool "Clock driver for Aspeed BMC SoCs"
> +	depends on ARCH_ASPEED || COMPILE_TEST
> +	default ARCH_ASPEED
> +	select MFD_SYSCON
> +	select RESET_CONTROLLER
> +	---help---
> +	??This driver supports the SoC clocks on the Aspeed BMC platforms.
> +
> +	??The G4 and G5 series, including the ast2400 and ast2500, are supported
> +	??by this driver.
> +
> ?config COMMON_CLK_S2MPS11
> ?	tristate "Clock driver for S2MPS1X/S5M8767 MFD"
> ?	depends on MFD_SEC_CORE || COMPILE_TEST
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index c99f363826f0..575c68919d9b 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -26,6 +26,7 @@ obj-$(CONFIG_ARCH_CLPS711X)		+= clk-clps711x.o
> ?obj-$(CONFIG_COMMON_CLK_CS2000_CP)	+= clk-cs2000-cp.o
> ?obj-$(CONFIG_ARCH_EFM32)		+= clk-efm32gg.o
> ?obj-$(CONFIG_COMMON_CLK_GEMINI)		+= clk-gemini.o
> +obj-$(CONFIG_COMMON_CLK_ASPEED)		+= clk-aspeed.o
> ?obj-$(CONFIG_ARCH_HIGHBANK)		+= clk-highbank.o
> ?obj-$(CONFIG_CLK_HSDK)			+= clk-hsdk-pll.o
> ?obj-$(CONFIG_COMMON_CLK_MAX77686)	+= clk-max77686.o
> diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/clk-aspeed.c
> new file mode 100644
> index 000000000000..a45eb351bb05
> --- /dev/null
> +++ b/drivers/clk/clk-aspeed.c
> @@ -0,0 +1,148 @@
> +/*
> + * Copyright 2017 IBM Corporation
> + *
> + * Joel Stanley <joel@jms.id.au>
> + *
> + * 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.
> + */
> +
> +#define pr_fmt(fmt) "clk-aspeed: " fmt
> +
> +#include <linux/clk-provider.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of_address.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/spinlock.h>
> +
> +#include <dt-bindings/clock/aspeed-clock.h>
> +
> +#define ASPEED_STRAP		0x70
> +
> +/* Keeps track of all clocks */
> +static struct clk_hw_onecell_data *aspeed_clk_data;
> +
> +static void __iomem *scu_base;
> +
> +/**
> + * struct aspeed_gate_data - Aspeed gated clocks
> + * @clock_idx: bit used to gate this clock in the clock register
> + * @reset_idx: bit used to reset this IP in the reset register. -1 if no
> + *?????????????reset is required when enabling the clock
> + * @name: the clock name
> + * @parent_name: the name of the parent clock
> + * @flags: standard clock framework flags
> + */
> +struct aspeed_gate_data {
> +	u8		clock_idx;
> +	s8		reset_idx;
> +	const char	*name;
> +	const char	*parent_name;
> +	unsigned long	flags;
> +};
> +
> +/**
> + * struct aspeed_clk_gate - Aspeed specific clk_gate structure
> + * @hw:		handle between common and hardware-specific interfaces
> + * @reg:	register controlling gate
> + * @clock_idx:	bit used to gate this clock in the clock register
> + * @reset_idx:	bit used to reset this IP in the reset register. -1 if no
> + *		reset is required when enabling the clock
> + * @flags:	hardware-specific flags
> + * @lock:	register lock
> + *
> + * Some of the clocks in the Aspeed SoC must be put in reset before enabling.
> + * This modified version of clk_gate allows an optional reset bit to be
> + * specified.
> + */
> +struct aspeed_clk_gate {
> +	struct clk_hw	hw;
> +	struct regmap	*map;
> +	u8		clock_idx;
> +	s8		reset_idx;
> +	u8		flags;
> +	spinlock_t	*lock;
> +};
> +
> +#define to_aspeed_clk_gate(_hw) container_of(_hw, struct aspeed_clk_gate, hw)
> +
> +/* TODO: ask Aspeed about the actual parent data */
> +static const struct aspeed_gate_data aspeed_gates[] __initconst = {
> +	/*				?clk rst???name			parent	flags */
> +	[ASPEED_CLK_GATE_ECLK] =	{??0, -1, "eclk-gate",		"eclk",	0 }, /* Video Engine */
> +	[ASPEED_CLK_GATE_GCLK] =	{??1,??7, "gclk-gate",		NULL,	0 }, /* 2D engine */
> +	[ASPEED_CLK_GATE_MCLK] =	{??2, -1, "mclk-gate",		"mpll",	CLK_IS_CRITICAL }, /* SDRAM */
> +	[ASPEED_CLK_GATE_VCLK] =	{??3,??6, "vclk-gate",		NULL,	0 }, /* Video Capture */
> +	[ASPEED_CLK_GATE_BCLK] =	{??4, 10, "bclk-gate",		"bclk",	0 }, /* PCIe/PCI */
> +	[ASPEED_CLK_GATE_DCLK] =	{??5, -1, "dclk-gate",		NULL,	0 }, /* DAC */
> +	[ASPEED_CLK_GATE_REFCLK] =	{??6, -1, "refclk-gate",	"clkin", CLK_IS_CRITICAL },
> +	[ASPEED_CLK_GATE_USBPORT2CLK] =	{??7,??3, "usb-port2-gate",	NULL,	0 }, /* USB2.0 Host port 2 */
> +	[ASPEED_CLK_GATE_LCLK] =	{??8,??5, "lclk-gate",		NULL,	0 }, /* LPC */
> +	[ASPEED_CLK_GATE_USBUHCICLK] =	{??9, 15, "usb-uhci-gate",	NULL,	0 }, /* USB1.1 (requires port 2 enabled) */
> +	[ASPEED_CLK_GATE_D1CLK] =	{ 10, 13, "d1clk-gate",		NULL,	0 }, /* GFX CRT */
> +	[ASPEED_CLK_GATE_YCLK] =	{ 13,??4, "yclk-gate",		NULL,	0 }, /* HAC */
> +	[ASPEED_CLK_GATE_USBPORT1CLK] = { 14, 14, "usb-port1-gate",	NULL,	0 }, /* USB2 hub/USB2 host port 1/USB1.1 dev */
> +	[ASPEED_CLK_GATE_UART1CLK] =	{ 15, -1, "uart1clk-gate",	"uart",	0 }, /* UART1 */
> +	[ASPEED_CLK_GATE_UART2CLK] =	{ 16, -1, "uart2clk-gate",	"uart",	0 }, /* UART2 */
> +	[ASPEED_CLK_GATE_UART5CLK] =	{ 17, -1, "uart5clk-gate",	"uart",	0 }, /* UART5 */
> +	[ASPEED_CLK_GATE_ESPICLK] =	{ 19, -1, "espiclk-gate",	NULL,	0 }, /* eSPI */
> +	[ASPEED_CLK_GATE_MAC1CLK] =	{ 20, 11, "mac1clk-gate",	"mac",	0 }, /* MAC1 */
> +	[ASPEED_CLK_GATE_MAC2CLK] =	{ 21, 12, "mac2clk-gate",	"mac",	0 }, /* MAC2 */
> +	[ASPEED_CLK_GATE_RSACLK] =	{ 24, -1, "rsaclk-gate",	NULL,	0 }, /* RSA */
> +	[ASPEED_CLK_GATE_UART3CLK] =	{ 25, -1, "uart3clk-gate",	"uart",	0 }, /* UART3 */
> +	[ASPEED_CLK_GATE_UART4CLK] =	{ 26, -1, "uart4clk-gate",	"uart",	0 }, /* UART4 */
> +	[ASPEED_CLK_GATE_SDCLKCLK] =	{ 27, 16, "sdclk-gate",		NULL,	0 }, /* SDIO/SD */
> +	[ASPEED_CLK_GATE_LHCCLK] =	{ 28, -1, "lhclk-gate",		"lhclk", 0 }, /* LPC master/LPC+ */
> +};
> +
> +static void __init aspeed_cc_init(struct device_node *np)
> +{
> +	struct regmap *map;
> +	u32 val;
> +	int ret;
> +	int i;
> +
> +	scu_base = of_iomap(np, 0);
> +	if (IS_ERR(scu_base))
> +		return;
> +
> +	aspeed_clk_data = kzalloc(sizeof(*aspeed_clk_data) +
> +			sizeof(*aspeed_clk_data->hws) * ASPEED_NUM_CLKS,
> +			GFP_KERNEL);
> +	if (!aspeed_clk_data)
> +		return;
> +
> +	/*
> +	?* This way all clocks fetched before the platform device probes,
> +	?* except those we assign here for early use, will be deferred.
> +	?*/
> +	for (i = 0; i < ASPEED_NUM_CLKS; i++)
> +		aspeed_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER);
> +
> +	map = syscon_node_to_regmap(np);
> +	if (IS_ERR(map)) {
> +		pr_err("no syscon regmap\n");
> +		return;
> +	}
> +	/*
> +	?* We check that the regmap works on this very first access,
> +	?* but as this is an MMIO-backed regmap, subsequent regmap
> +	?* access is not going to fail and we skip error checks from
> +	?* this point.
> +	?*/
> +	ret = regmap_read(map, ASPEED_STRAP, &val);
> +	if (ret) {
> +		pr_err("failed to read strapping register\n");
> +		return;
> +	}
> +
> +	aspeed_clk_data->num = ASPEED_NUM_CLKS;
> +	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, aspeed_clk_data);
> +	if (ret)
> +		pr_err("failed to add DT provider: %d\n", ret);
> +};
> +CLK_OF_DECLARE_DRIVER(aspeed_cc_g5, "aspeed,ast2500-scu", aspeed_cc_init);
> +CLK_OF_DECLARE_DRIVER(aspeed_cc_g4, "aspeed,ast2400-scu", aspeed_cc_init);
> diff --git a/include/dt-bindings/clock/aspeed-clock.h b/include/dt-bindings/clock/aspeed-clock.h
> new file mode 100644
> index 000000000000..4a99421d77c8
> --- /dev/null
> +++ b/include/dt-bindings/clock/aspeed-clock.h
> @@ -0,0 +1,42 @@
> +#ifndef DT_BINDINGS_ASPEED_CLOCK_H
> +#define DT_BINDINGS_ASPEED_CLOCK_H
> +
> +#define ASPEED_CLK_GATE_ECLK		0
> +#define ASPEED_CLK_GATE_GCLK		1
> +#define ASPEED_CLK_GATE_MCLK		2
> +#define ASPEED_CLK_GATE_VCLK		3
> +#define ASPEED_CLK_GATE_BCLK		4
> +#define ASPEED_CLK_GATE_DCLK		5
> +#define ASPEED_CLK_GATE_REFCLK		6
> +#define ASPEED_CLK_GATE_USBPORT2CLK	7
> +#define ASPEED_CLK_GATE_LCLK		8
> +#define ASPEED_CLK_GATE_USBUHCICLK	9
> +#define ASPEED_CLK_GATE_D1CLK		10
> +#define ASPEED_CLK_GATE_YCLK		11
> +#define ASPEED_CLK_GATE_USBPORT1CLK	12
> +#define ASPEED_CLK_GATE_UART1CLK	13
> +#define ASPEED_CLK_GATE_UART2CLK	14
> +#define ASPEED_CLK_GATE_UART5CLK	15
> +#define ASPEED_CLK_GATE_ESPICLK		16
> +#define ASPEED_CLK_GATE_MAC1CLK		17
> +#define ASPEED_CLK_GATE_MAC2CLK		18
> +#define ASPEED_CLK_GATE_RSACLK		19
> +#define ASPEED_CLK_GATE_UART3CLK	20
> +#define ASPEED_CLK_GATE_UART4CLK	21
> +#define ASPEED_CLK_GATE_SDCLKCLK	22
> +#define ASPEED_CLK_GATE_LHCCLK		23
> +#define ASPEED_CLK_HPLL			24
> +#define ASPEED_CLK_AHB			25
> +#define ASPEED_CLK_APB			26
> +#define ASPEED_CLK_UART			27
> +#define ASPEED_CLK_SDIO			28
> +#define ASPEED_CLK_ECLK			29
> +#define ASPEED_CLK_ECLK_MUX		30
> +#define ASPEED_CLK_LHCLK		31
> +#define ASPEED_CLK_MAC			32
> +#define ASPEED_CLK_BCLK			33
> +#define ASPEED_CLK_MPLL			34
> +
> +#define ASPEED_NUM_CLKS			35
> +
> +#endif
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20171005/9e67fbdd/attachment-0001.sig>

^ permalink raw reply

* Re: [PATCH v4 1/5] clk: Add clock driver for ASPEED BMC SoCs
From: Andrew Jeffery @ 2017-10-05  6:36 UTC (permalink / raw)
  To: Joel Stanley, Lee Jones, Michael Turquette, Stephen Boyd
  Cc: linux-kernel, linux-clk, linux-arm-kernel, Benjamin Herrenschmidt,
	Jeremy Kerr, Rick Altherr, Ryan Chen, Arnd Bergmann
In-Reply-To: <20171003065540.11722-2-joel@jms.id.au>

[-- Attachment #1: Type: text/plain, Size: 10622 bytes --]

On Tue, 2017-10-03 at 17:25 +1030, Joel Stanley wrote:
> This adds the stub of a driver for the ASPEED SoCs. The clocks are
> defined and the static registration is set up.
> 
> Signed-off-by: Joel Stanley <joel@jms.id.au>

With respect to use of the Aspeed hardware,

Reviewed-by: Andrew Jeffery <andrew@aj.id.au>

> ---
> v3:
>  - use named initlisers for aspeed_gates table
>  - fix clocks typo
>  - Move ASPEED_NUM_CLKS to the bottom of the list
>  - Put gates at the start of the list, so we can use them to initalise
>    the aspeed_gates table
>  - Add ASPEED_CLK_SELECTION_2
>  - Set parent of network MAC gates
> ---
>  drivers/clk/Kconfig                      |  12 +++
>  drivers/clk/Makefile                     |   1 +
>  drivers/clk/clk-aspeed.c                 | 148 +++++++++++++++++++++++++++++++
>  include/dt-bindings/clock/aspeed-clock.h |  42 +++++++++
>  4 files changed, 203 insertions(+)
>  create mode 100644 drivers/clk/clk-aspeed.c
>  create mode 100644 include/dt-bindings/clock/aspeed-clock.h
> 
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index 1c4e1aa6767e..9abe063ef8d2 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -142,6 +142,18 @@ config COMMON_CLK_GEMINI
>  	  This driver supports the SoC clocks on the Cortina Systems Gemini
>  	  platform, also known as SL3516 or CS3516.
>  
> +config COMMON_CLK_ASPEED
> +	bool "Clock driver for Aspeed BMC SoCs"
> +	depends on ARCH_ASPEED || COMPILE_TEST
> +	default ARCH_ASPEED
> +	select MFD_SYSCON
> +	select RESET_CONTROLLER
> +	---help---
> +	  This driver supports the SoC clocks on the Aspeed BMC platforms.
> +
> +	  The G4 and G5 series, including the ast2400 and ast2500, are supported
> +	  by this driver.
> +
>  config COMMON_CLK_S2MPS11
>  	tristate "Clock driver for S2MPS1X/S5M8767 MFD"
>  	depends on MFD_SEC_CORE || COMPILE_TEST
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index c99f363826f0..575c68919d9b 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -26,6 +26,7 @@ obj-$(CONFIG_ARCH_CLPS711X)		+= clk-clps711x.o
>  obj-$(CONFIG_COMMON_CLK_CS2000_CP)	+= clk-cs2000-cp.o
>  obj-$(CONFIG_ARCH_EFM32)		+= clk-efm32gg.o
>  obj-$(CONFIG_COMMON_CLK_GEMINI)		+= clk-gemini.o
> +obj-$(CONFIG_COMMON_CLK_ASPEED)		+= clk-aspeed.o
>  obj-$(CONFIG_ARCH_HIGHBANK)		+= clk-highbank.o
>  obj-$(CONFIG_CLK_HSDK)			+= clk-hsdk-pll.o
>  obj-$(CONFIG_COMMON_CLK_MAX77686)	+= clk-max77686.o
> diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/clk-aspeed.c
> new file mode 100644
> index 000000000000..a45eb351bb05
> --- /dev/null
> +++ b/drivers/clk/clk-aspeed.c
> @@ -0,0 +1,148 @@
> +/*
> + * Copyright 2017 IBM Corporation
> + *
> + * Joel Stanley <joel@jms.id.au>
> + *
> + * 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.
> + */
> +
> +#define pr_fmt(fmt) "clk-aspeed: " fmt
> +
> +#include <linux/clk-provider.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of_address.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/spinlock.h>
> +
> +#include <dt-bindings/clock/aspeed-clock.h>
> +
> +#define ASPEED_STRAP		0x70
> +
> +/* Keeps track of all clocks */
> +static struct clk_hw_onecell_data *aspeed_clk_data;
> +
> +static void __iomem *scu_base;
> +
> +/**
> + * struct aspeed_gate_data - Aspeed gated clocks
> + * @clock_idx: bit used to gate this clock in the clock register
> + * @reset_idx: bit used to reset this IP in the reset register. -1 if no
> + *             reset is required when enabling the clock
> + * @name: the clock name
> + * @parent_name: the name of the parent clock
> + * @flags: standard clock framework flags
> + */
> +struct aspeed_gate_data {
> +	u8		clock_idx;
> +	s8		reset_idx;
> +	const char	*name;
> +	const char	*parent_name;
> +	unsigned long	flags;
> +};
> +
> +/**
> + * struct aspeed_clk_gate - Aspeed specific clk_gate structure
> + * @hw:		handle between common and hardware-specific interfaces
> + * @reg:	register controlling gate
> + * @clock_idx:	bit used to gate this clock in the clock register
> + * @reset_idx:	bit used to reset this IP in the reset register. -1 if no
> + *		reset is required when enabling the clock
> + * @flags:	hardware-specific flags
> + * @lock:	register lock
> + *
> + * Some of the clocks in the Aspeed SoC must be put in reset before enabling.
> + * This modified version of clk_gate allows an optional reset bit to be
> + * specified.
> + */
> +struct aspeed_clk_gate {
> +	struct clk_hw	hw;
> +	struct regmap	*map;
> +	u8		clock_idx;
> +	s8		reset_idx;
> +	u8		flags;
> +	spinlock_t	*lock;
> +};
> +
> +#define to_aspeed_clk_gate(_hw) container_of(_hw, struct aspeed_clk_gate, hw)
> +
> +/* TODO: ask Aspeed about the actual parent data */
> +static const struct aspeed_gate_data aspeed_gates[] __initconst = {
> +	/*				 clk rst   name			parent	flags */
> +	[ASPEED_CLK_GATE_ECLK] =	{  0, -1, "eclk-gate",		"eclk",	0 }, /* Video Engine */
> +	[ASPEED_CLK_GATE_GCLK] =	{  1,  7, "gclk-gate",		NULL,	0 }, /* 2D engine */
> +	[ASPEED_CLK_GATE_MCLK] =	{  2, -1, "mclk-gate",		"mpll",	CLK_IS_CRITICAL }, /* SDRAM */
> +	[ASPEED_CLK_GATE_VCLK] =	{  3,  6, "vclk-gate",		NULL,	0 }, /* Video Capture */
> +	[ASPEED_CLK_GATE_BCLK] =	{  4, 10, "bclk-gate",		"bclk",	0 }, /* PCIe/PCI */
> +	[ASPEED_CLK_GATE_DCLK] =	{  5, -1, "dclk-gate",		NULL,	0 }, /* DAC */
> +	[ASPEED_CLK_GATE_REFCLK] =	{  6, -1, "refclk-gate",	"clkin", CLK_IS_CRITICAL },
> +	[ASPEED_CLK_GATE_USBPORT2CLK] =	{  7,  3, "usb-port2-gate",	NULL,	0 }, /* USB2.0 Host port 2 */
> +	[ASPEED_CLK_GATE_LCLK] =	{  8,  5, "lclk-gate",		NULL,	0 }, /* LPC */
> +	[ASPEED_CLK_GATE_USBUHCICLK] =	{  9, 15, "usb-uhci-gate",	NULL,	0 }, /* USB1.1 (requires port 2 enabled) */
> +	[ASPEED_CLK_GATE_D1CLK] =	{ 10, 13, "d1clk-gate",		NULL,	0 }, /* GFX CRT */
> +	[ASPEED_CLK_GATE_YCLK] =	{ 13,  4, "yclk-gate",		NULL,	0 }, /* HAC */
> +	[ASPEED_CLK_GATE_USBPORT1CLK] = { 14, 14, "usb-port1-gate",	NULL,	0 }, /* USB2 hub/USB2 host port 1/USB1.1 dev */
> +	[ASPEED_CLK_GATE_UART1CLK] =	{ 15, -1, "uart1clk-gate",	"uart",	0 }, /* UART1 */
> +	[ASPEED_CLK_GATE_UART2CLK] =	{ 16, -1, "uart2clk-gate",	"uart",	0 }, /* UART2 */
> +	[ASPEED_CLK_GATE_UART5CLK] =	{ 17, -1, "uart5clk-gate",	"uart",	0 }, /* UART5 */
> +	[ASPEED_CLK_GATE_ESPICLK] =	{ 19, -1, "espiclk-gate",	NULL,	0 }, /* eSPI */
> +	[ASPEED_CLK_GATE_MAC1CLK] =	{ 20, 11, "mac1clk-gate",	"mac",	0 }, /* MAC1 */
> +	[ASPEED_CLK_GATE_MAC2CLK] =	{ 21, 12, "mac2clk-gate",	"mac",	0 }, /* MAC2 */
> +	[ASPEED_CLK_GATE_RSACLK] =	{ 24, -1, "rsaclk-gate",	NULL,	0 }, /* RSA */
> +	[ASPEED_CLK_GATE_UART3CLK] =	{ 25, -1, "uart3clk-gate",	"uart",	0 }, /* UART3 */
> +	[ASPEED_CLK_GATE_UART4CLK] =	{ 26, -1, "uart4clk-gate",	"uart",	0 }, /* UART4 */
> +	[ASPEED_CLK_GATE_SDCLKCLK] =	{ 27, 16, "sdclk-gate",		NULL,	0 }, /* SDIO/SD */
> +	[ASPEED_CLK_GATE_LHCCLK] =	{ 28, -1, "lhclk-gate",		"lhclk", 0 }, /* LPC master/LPC+ */
> +};
> +
> +static void __init aspeed_cc_init(struct device_node *np)
> +{
> +	struct regmap *map;
> +	u32 val;
> +	int ret;
> +	int i;
> +
> +	scu_base = of_iomap(np, 0);
> +	if (IS_ERR(scu_base))
> +		return;
> +
> +	aspeed_clk_data = kzalloc(sizeof(*aspeed_clk_data) +
> +			sizeof(*aspeed_clk_data->hws) * ASPEED_NUM_CLKS,
> +			GFP_KERNEL);
> +	if (!aspeed_clk_data)
> +		return;
> +
> +	/*
> +	 * This way all clocks fetched before the platform device probes,
> +	 * except those we assign here for early use, will be deferred.
> +	 */
> +	for (i = 0; i < ASPEED_NUM_CLKS; i++)
> +		aspeed_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER);
> +
> +	map = syscon_node_to_regmap(np);
> +	if (IS_ERR(map)) {
> +		pr_err("no syscon regmap\n");
> +		return;
> +	}
> +	/*
> +	 * We check that the regmap works on this very first access,
> +	 * but as this is an MMIO-backed regmap, subsequent regmap
> +	 * access is not going to fail and we skip error checks from
> +	 * this point.
> +	 */
> +	ret = regmap_read(map, ASPEED_STRAP, &val);
> +	if (ret) {
> +		pr_err("failed to read strapping register\n");
> +		return;
> +	}
> +
> +	aspeed_clk_data->num = ASPEED_NUM_CLKS;
> +	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, aspeed_clk_data);
> +	if (ret)
> +		pr_err("failed to add DT provider: %d\n", ret);
> +};
> +CLK_OF_DECLARE_DRIVER(aspeed_cc_g5, "aspeed,ast2500-scu", aspeed_cc_init);
> +CLK_OF_DECLARE_DRIVER(aspeed_cc_g4, "aspeed,ast2400-scu", aspeed_cc_init);
> diff --git a/include/dt-bindings/clock/aspeed-clock.h b/include/dt-bindings/clock/aspeed-clock.h
> new file mode 100644
> index 000000000000..4a99421d77c8
> --- /dev/null
> +++ b/include/dt-bindings/clock/aspeed-clock.h
> @@ -0,0 +1,42 @@
> +#ifndef DT_BINDINGS_ASPEED_CLOCK_H
> +#define DT_BINDINGS_ASPEED_CLOCK_H
> +
> +#define ASPEED_CLK_GATE_ECLK		0
> +#define ASPEED_CLK_GATE_GCLK		1
> +#define ASPEED_CLK_GATE_MCLK		2
> +#define ASPEED_CLK_GATE_VCLK		3
> +#define ASPEED_CLK_GATE_BCLK		4
> +#define ASPEED_CLK_GATE_DCLK		5
> +#define ASPEED_CLK_GATE_REFCLK		6
> +#define ASPEED_CLK_GATE_USBPORT2CLK	7
> +#define ASPEED_CLK_GATE_LCLK		8
> +#define ASPEED_CLK_GATE_USBUHCICLK	9
> +#define ASPEED_CLK_GATE_D1CLK		10
> +#define ASPEED_CLK_GATE_YCLK		11
> +#define ASPEED_CLK_GATE_USBPORT1CLK	12
> +#define ASPEED_CLK_GATE_UART1CLK	13
> +#define ASPEED_CLK_GATE_UART2CLK	14
> +#define ASPEED_CLK_GATE_UART5CLK	15
> +#define ASPEED_CLK_GATE_ESPICLK		16
> +#define ASPEED_CLK_GATE_MAC1CLK		17
> +#define ASPEED_CLK_GATE_MAC2CLK		18
> +#define ASPEED_CLK_GATE_RSACLK		19
> +#define ASPEED_CLK_GATE_UART3CLK	20
> +#define ASPEED_CLK_GATE_UART4CLK	21
> +#define ASPEED_CLK_GATE_SDCLKCLK	22
> +#define ASPEED_CLK_GATE_LHCCLK		23
> +#define ASPEED_CLK_HPLL			24
> +#define ASPEED_CLK_AHB			25
> +#define ASPEED_CLK_APB			26
> +#define ASPEED_CLK_UART			27
> +#define ASPEED_CLK_SDIO			28
> +#define ASPEED_CLK_ECLK			29
> +#define ASPEED_CLK_ECLK_MUX		30
> +#define ASPEED_CLK_LHCLK		31
> +#define ASPEED_CLK_MAC			32
> +#define ASPEED_CLK_BCLK			33
> +#define ASPEED_CLK_MPLL			34
> +
> +#define ASPEED_NUM_CLKS			35
> +
> +#endif

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: [Outreachy kernel] [PATCH] nftables: Change size_t len to size_t size
From: Julia Lawall @ 2017-10-05  6:36 UTC (permalink / raw)
  To: Meghana Madhyastha; +Cc: pablo, outreachy-kernel
In-Reply-To: <20171005032543.GA28390@meghana-HP-Pavilion-Notebook>



On Thu, 5 Oct 2017, Meghana Madhyastha wrote:

> On Wed, Oct 04, 2017 at 10:15:00PM +0200, Julia Lawall wrote:
> >
> >
> > On Wed, 4 Oct 2017, Meghana Madhyastha wrote:
> >
> > > Change the variable name from size_t len to
> > > size_t size in the sprintf functions for
> > > consistency.
> >
> > It looks like a lot of changes.  Is size_t size already used in a lot of
> > other places?
>
> size_t size is used in most of the other places (in more places than size_t
> len in other parts of the codebase) so Pablo had asked me to convert size_t
> len to size_t size.

OK.

julia

>
> Regards,
> Meghana
>
> > Try to make log messages the use more of the horizontal space.
> >
> > julia
> >
> > >
> > > Signed-off-by: Meghana Madhyastha <meghana.madhyastha@gmail.com>
> > > ---
> > >  src/expr/counter.c   | 12 ++++++------
> > >  src/expr/ct.c        |  8 ++++----
> > >  src/expr/dup.c       | 16 ++++++++--------
> > >  src/expr/exthdr.c    | 14 +++++++-------
> > >  src/expr/fib.c       |  8 ++++----
> > >  src/expr/fwd.c       | 12 ++++++------
> > >  src/expr/hash.c      |  8 ++++----
> > >  src/expr/immediate.c | 12 ++++++------
> > >  src/expr/limit.c     | 12 ++++++------
> > >  src/expr/log.c       |  8 ++++----
> > >  src/expr/masq.c      | 14 +++++++-------
> > >  src/expr/match.c     |  8 ++++----
> > >  src/expr/meta.c      | 14 +++++++-------
> > >  src/expr/numgen.c    |  8 ++++----
> > >  src/expr/objref.c    | 14 +++++++-------
> > >  src/expr/payload.c   | 10 +++++-----
> > >  src/expr/queue.c     | 24 ++++++++++++------------
> > >  src/expr/quota.c     | 12 ++++++------
> > >  src/expr/redir.c     | 18 +++++++++---------
> > >  src/expr/reject.c    | 12 ++++++------
> > >  src/expr/rt.c        | 12 ++++++------
> > >  src/expr/target.c    |  8 ++++----
> > >  22 files changed, 132 insertions(+), 132 deletions(-)
> > >
> > > diff --git a/src/expr/counter.c b/src/expr/counter.c
> > > index 5c196d4..4de6b92 100644
> > > --- a/src/expr/counter.c
> > > +++ b/src/expr/counter.c
> > > @@ -151,28 +151,28 @@ static int nftnl_expr_counter_export(char *buf, size_t size,
> > >  	return nftnl_buf_done(&b);
> > >  }
> > >
> > > -static int nftnl_expr_counter_snprintf_default(char *buf, size_t len,
> > > +static int nftnl_expr_counter_snprintf_default(char *buf, size_t size,
> > >  					       const struct nftnl_expr *e)
> > >  {
> > >  	struct nftnl_expr_counter *ctr = nftnl_expr_data(e);
> > >
> > > -	return snprintf(buf, len, "pkts %"PRIu64" bytes %"PRIu64" ",
> > > +	return snprintf(buf, size, "pkts %"PRIu64" bytes %"PRIu64" ",
> > >  			ctr->pkts, ctr->bytes);
> > >  }
> > >
> > > -static int nftnl_expr_counter_snprintf(char *buf, size_t len, uint32_t type,
> > > +static int nftnl_expr_counter_snprintf(char *buf, size_t size, uint32_t type,
> > >  				       uint32_t flags,
> > >  				       const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_counter_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_counter_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_counter_export(buf, len, e, type);
> > > +		return nftnl_expr_counter_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/ct.c b/src/expr/ct.c
> > > index 021a277..396bee0 100644
> > > --- a/src/expr/ct.c
> > > +++ b/src/expr/ct.c
> > > @@ -314,18 +314,18 @@ nftnl_expr_ct_snprintf_default(char *buf, size_t size,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_ct_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_ct_snprintf(char *buf, size_t size, uint32_t type,
> > >  		       uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_ct_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_ct_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_ct_export(buf, len, e, type);
> > > +		return nftnl_expr_ct_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/dup.c b/src/expr/dup.c
> > > index e2171f4..f67331b 100644
> > > --- a/src/expr/dup.c
> > > +++ b/src/expr/dup.c
> > > @@ -147,38 +147,38 @@ static int nftnl_expr_dup_export(char *buf, size_t size,
> > >  	return nftnl_buf_done(&b);
> > >  }
> > >
> > > -static int nftnl_expr_dup_snprintf_default(char *buf, size_t len,
> > > +static int nftnl_expr_dup_snprintf_default(char *buf, size_t size,
> > >  					   const struct nftnl_expr *e,
> > >  					   uint32_t flags)
> > >  {
> > > -	int remain = len, offset = 0, ret;
> > > +	int remain = size, offset = 0, ret;
> > >  	struct nftnl_expr_dup *dup = nftnl_expr_data(e);
> > >
> > >  	if (e->flags & (1 << NFTNL_EXPR_DUP_SREG_ADDR)) {
> > > -		ret = snprintf(buf + offset, len, "sreg_addr %u ", dup->sreg_addr);
> > > +		ret = snprintf(buf + offset, size, "sreg_addr %u ", dup->sreg_addr);
> > >  		SNPRINTF_BUFFER_SIZE(ret, remain, offset);
> > >  	}
> > >
> > >  	if (e->flags & (1 << NFTNL_EXPR_DUP_SREG_DEV)) {
> > > -		ret = snprintf(buf + offset, len, "sreg_dev %u ", dup->sreg_dev);
> > > +		ret = snprintf(buf + offset, size, "sreg_dev %u ", dup->sreg_dev);
> > >  		SNPRINTF_BUFFER_SIZE(ret, remain, offset);
> > >  	}
> > >
> > >  	return offset;
> > >  }
> > >
> > > -static int nftnl_expr_dup_snprintf(char *buf, size_t len, uint32_t type,
> > > +static int nftnl_expr_dup_snprintf(char *buf, size_t size, uint32_t type,
> > >  				   uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_dup_snprintf_default(buf, len, e, flags);
> > > +		return nftnl_expr_dup_snprintf_default(buf, size, e, flags);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_dup_export(buf, len, e, type);
> > > +		return nftnl_expr_dup_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/exthdr.c b/src/expr/exthdr.c
> > > index 11766fa..12f49d8 100644
> > > --- a/src/expr/exthdr.c
> > > +++ b/src/expr/exthdr.c
> > > @@ -317,37 +317,37 @@ static int nftnl_expr_exthdr_export(char *buf, size_t len,
> > >  	return nftnl_buf_done(&b);
> > >  }
> > >
> > > -static int nftnl_expr_exthdr_snprintf_default(char *buf, size_t len,
> > > +static int nftnl_expr_exthdr_snprintf_default(char *buf, size_t size,
> > >  					      const struct nftnl_expr *e)
> > >  {
> > >  	struct nftnl_expr_exthdr *exthdr = nftnl_expr_data(e);
> > >
> > >  	if (e->flags & (1 << NFTNL_EXPR_EXTHDR_DREG))
> > > -		return snprintf(buf, len, "load%s %ub @ %u + %u%s => reg %u ",
> > > +		return snprintf(buf, size, "load%s %ub @ %u + %u%s => reg %u ",
> > >  				op2str(exthdr->op), exthdr->len, exthdr->type,
> > >  				exthdr->offset,
> > >  				exthdr->flags & NFT_EXTHDR_F_PRESENT ? " present" : "",
> > >  				exthdr->dreg);
> > >  	else
> > > -		return snprintf(buf, len, "write%s reg %u => %ub @ %u + %u ",
> > > +		return snprintf(buf, size, "write%s reg %u => %ub @ %u + %u ",
> > >  				op2str(exthdr->op), exthdr->sreg, exthdr->len, exthdr->type,
> > >  				exthdr->offset);
> > >
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_exthdr_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_exthdr_snprintf(char *buf, size_t size, uint32_t type,
> > >  			   uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_exthdr_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_exthdr_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_exthdr_export(buf, len, e, type);
> > > +		return nftnl_expr_exthdr_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/fib.c b/src/expr/fib.c
> > > index cbadeef..cb62020 100644
> > > --- a/src/expr/fib.c
> > > +++ b/src/expr/fib.c
> > > @@ -233,18 +233,18 @@ static int nftnl_expr_fib_export(char *buf, size_t size,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_fib_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_fib_snprintf(char *buf, size_t size, uint32_t type,
> > >  			 uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_fib_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_fib_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_fib_export(buf, len, e, type);
> > > +		return nftnl_expr_fib_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/fwd.c b/src/expr/fwd.c
> > > index 38923df..9b5e555 100644
> > > --- a/src/expr/fwd.c
> > > +++ b/src/expr/fwd.c
> > > @@ -128,11 +128,11 @@ static int nftnl_expr_fwd_export(char *buf, size_t size,
> > >  	return nftnl_buf_done(&b);
> > >  }
> > >
> > > -static int nftnl_expr_fwd_snprintf_default(char *buf, size_t len,
> > > +static int nftnl_expr_fwd_snprintf_default(char *buf, size_t size,
> > >  					   const struct nftnl_expr *e,
> > >  					   uint32_t flags)
> > >  {
> > > -	int remain = len, offset = 0, ret;
> > > +	int remain = size, offset = 0, ret;
> > >  	struct nftnl_expr_fwd *fwd = nftnl_expr_data(e);
> > >
> > >  	if (e->flags & (1 << NFTNL_EXPR_FWD_SREG_DEV)) {
> > > @@ -144,18 +144,18 @@ static int nftnl_expr_fwd_snprintf_default(char *buf, size_t len,
> > >  	return offset;
> > >  }
> > >
> > > -static int nftnl_expr_fwd_snprintf(char *buf, size_t len, uint32_t type,
> > > +static int nftnl_expr_fwd_snprintf(char *buf, size_t size, uint32_t type,
> > >  				   uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_fwd_snprintf_default(buf, len, e, flags);
> > > +		return nftnl_expr_fwd_snprintf_default(buf, size, e, flags);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_fwd_export(buf, len, e, type);
> > > +		return nftnl_expr_fwd_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/hash.c b/src/expr/hash.c
> > > index 066c790..6a52308 100644
> > > --- a/src/expr/hash.c
> > > +++ b/src/expr/hash.c
> > > @@ -285,18 +285,18 @@ static int nftnl_expr_hash_export(char *buf, size_t size,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_hash_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_hash_snprintf(char *buf, size_t size, uint32_t type,
> > >  			 uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_hash_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_hash_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_hash_export(buf, len, e, type);
> > > +		return nftnl_expr_hash_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/immediate.c b/src/expr/immediate.c
> > > index aba84ea..5cdad03 100644
> > > --- a/src/expr/immediate.c
> > > +++ b/src/expr/immediate.c
> > > @@ -229,11 +229,11 @@ nftnl_expr_immediate_export(char *buf, size_t size, const struct nftnl_expr *e,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_immediate_snprintf_default(char *buf, size_t len,
> > > +nftnl_expr_immediate_snprintf_default(char *buf, size_t size,
> > >  				      const struct nftnl_expr *e,
> > >  				      uint32_t flags)
> > >  {
> > > -	int remain = len, offset = 0, ret;
> > > +	int remain = size, offset = 0, ret;
> > >  	struct nftnl_expr_immediate *imm = nftnl_expr_data(e);
> > >
> > >  	ret = snprintf(buf, remain, "reg %u ", imm->dreg);
> > > @@ -259,18 +259,18 @@ nftnl_expr_immediate_snprintf_default(char *buf, size_t len,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_immediate_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_immediate_snprintf(char *buf, size_t size, uint32_t type,
> > >  			      uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch(type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_immediate_snprintf_default(buf, len, e, flags);
> > > +		return nftnl_expr_immediate_snprintf_default(buf, size, e, flags);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_immediate_export(buf, len, e, type);
> > > +		return nftnl_expr_immediate_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/limit.c b/src/expr/limit.c
> > > index 8e1f02a..3927dbf 100644
> > > --- a/src/expr/limit.c
> > > +++ b/src/expr/limit.c
> > > @@ -229,29 +229,29 @@ static const char *limit_to_type(enum nft_limit_type type)
> > >  	}
> > >  }
> > >
> > > -static int nftnl_expr_limit_snprintf_default(char *buf, size_t len,
> > > +static int nftnl_expr_limit_snprintf_default(char *buf, size_t size,
> > >  					     const struct nftnl_expr *e)
> > >  {
> > >  	struct nftnl_expr_limit *limit = nftnl_expr_data(e);
> > >
> > > -	return snprintf(buf, len, "rate %"PRIu64"/%s burst %u type %s flags 0x%x ",
> > > +	return snprintf(buf, size, "rate %"PRIu64"/%s burst %u type %s flags 0x%x ",
> > >  			limit->rate, get_unit(limit->unit), limit->burst,
> > >  			limit_to_type(limit->type), limit->flags);
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_limit_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_limit_snprintf(char *buf, size_t size, uint32_t type,
> > >  			  uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch(type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_limit_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_limit_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_limit_export(buf, len, e, type);
> > > +		return nftnl_expr_limit_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/log.c b/src/expr/log.c
> > > index 161327b..48abc9c 100644
> > > --- a/src/expr/log.c
> > > +++ b/src/expr/log.c
> > > @@ -298,18 +298,18 @@ static int nftnl_expr_log_export(char *buf, size_t size,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_log_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_log_snprintf(char *buf, size_t size, uint32_t type,
> > >  			uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch(type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_log_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_log_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_log_export(buf, len, e, type);
> > > +		return nftnl_expr_log_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/masq.c b/src/expr/masq.c
> > > index 1c75ee9..76d3eea 100644
> > > --- a/src/expr/masq.c
> > > +++ b/src/expr/masq.c
> > > @@ -171,15 +171,15 @@ static int nftnl_expr_masq_export(char *buf, size_t size,
> > >  	return nftnl_buf_done(&b);
> > >  }
> > >
> > > -static int nftnl_expr_masq_snprintf_default(char *buf, size_t len,
> > > +static int nftnl_expr_masq_snprintf_default(char *buf, size_t size,
> > >  					    const struct nftnl_expr *e)
> > >  {
> > >  	struct nftnl_expr_masq *masq = nftnl_expr_data(e);
> > >
> > >  	if (e->flags & (1 << NFTNL_EXPR_MASQ_FLAGS))
> > > -		return snprintf(buf, len, "flags 0x%x ", masq->flags);
> > > +		return snprintf(buf, size, "flags 0x%x ", masq->flags);
> > >  	if (e->flags & (1 << NFTNL_EXPR_MASQ_REG_PROTO_MIN)) {
> > > -		return snprintf(buf, len,
> > > +		return snprintf(buf, size,
> > >  				"proto_min reg %u proto_max reg %u ",
> > >  				masq->sreg_proto_min, masq->sreg_proto_max);
> > >  	}
> > > @@ -187,18 +187,18 @@ static int nftnl_expr_masq_snprintf_default(char *buf, size_t len,
> > >  	return 0;
> > >  }
> > >
> > > -static int nftnl_expr_masq_snprintf(char *buf, size_t len, uint32_t type,
> > > +static int nftnl_expr_masq_snprintf(char *buf, size_t size, uint32_t type,
> > >  				    uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_masq_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_masq_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_masq_export(buf, len, e, type);
> > > +		return nftnl_expr_masq_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/match.c b/src/expr/match.c
> > > index af659b3..431c339 100644
> > > --- a/src/expr/match.c
> > > +++ b/src/expr/match.c
> > > @@ -195,21 +195,21 @@ static int nftnl_expr_match_export(char *buf, size_t size,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_match_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_match_snprintf(char *buf, size_t size, uint32_t type,
> > >  			  uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > >  	struct nftnl_expr_match *match = nftnl_expr_data(e);
> > >
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return snprintf(buf, len, "name %s rev %u ",
> > > +		return snprintf(buf, size, "name %s rev %u ",
> > >  				match->name, match->rev);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_match_export(buf, len, e, type);
> > > +		return nftnl_expr_match_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/meta.c b/src/expr/meta.c
> > > index b5c27e6..95e84ad 100644
> > > --- a/src/expr/meta.c
> > > +++ b/src/expr/meta.c
> > > @@ -216,17 +216,17 @@ static int nftnl_expr_meta_json_parse(struct nftnl_expr *e, json_t *root,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_meta_snprintf_default(char *buf, size_t len,
> > > +nftnl_expr_meta_snprintf_default(char *buf, size_t size,
> > >  				 const struct nftnl_expr *e)
> > >  {
> > >  	struct nftnl_expr_meta *meta = nftnl_expr_data(e);
> > >
> > >  	if (e->flags & (1 << NFTNL_EXPR_META_SREG)) {
> > > -		return snprintf(buf, len, "set %s with reg %u ",
> > > +		return snprintf(buf, size, "set %s with reg %u ",
> > >  				meta_key2str(meta->key), meta->sreg);
> > >  	}
> > >  	if (e->flags & (1 << NFTNL_EXPR_META_DREG)) {
> > > -		return snprintf(buf, len, "load %s => reg %u ",
> > > +		return snprintf(buf, size, "load %s => reg %u ",
> > >  				meta_key2str(meta->key), meta->dreg);
> > >  	}
> > >  	return 0;
> > > @@ -249,18 +249,18 @@ static int nftnl_expr_meta_export(char *buf, size_t size,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_meta_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_meta_snprintf(char *buf, size_t size, uint32_t type,
> > >  			 uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_meta_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_meta_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_meta_export(buf, len, e, type);
> > > +		return nftnl_expr_meta_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/numgen.c b/src/expr/numgen.c
> > > index 9b5b1b7..83c493a 100644
> > > --- a/src/expr/numgen.c
> > > +++ b/src/expr/numgen.c
> > > @@ -221,18 +221,18 @@ static int nftnl_expr_ng_export(char *buf, size_t size,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_ng_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_ng_snprintf(char *buf, size_t size, uint32_t type,
> > >  		       uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_ng_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_ng_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_ng_export(buf, len, e, type);
> > > +		return nftnl_expr_ng_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/objref.c b/src/expr/objref.c
> > > index b4b3383..340dc67 100644
> > > --- a/src/expr/objref.c
> > > +++ b/src/expr/objref.c
> > > @@ -219,32 +219,32 @@ static int nftnl_expr_objref_export(char *buf, size_t size,
> > >  	return nftnl_buf_done(&b);
> > >  }
> > >
> > > -static int nftnl_expr_objref_snprintf_default(char *buf, size_t len,
> > > +static int nftnl_expr_objref_snprintf_default(char *buf, size_t size,
> > >  					      const struct nftnl_expr *e)
> > >  {
> > >  	struct nftnl_expr_objref *objref = nftnl_expr_data(e);
> > >
> > >  	if (e->flags & (1 << NFTNL_EXPR_OBJREF_SET_SREG))
> > > -		return snprintf(buf, len, "sreg %u set %s id %u ",
> > > +		return snprintf(buf, size, "sreg %u set %s id %u ",
> > >  				objref->set.sreg, objref->set.name, objref->set.id);
> > >  	else
> > > -		return snprintf(buf, len, "type %u name %s ",
> > > +		return snprintf(buf, size, "type %u name %s ",
> > >  				objref->imm.type, objref->imm.name);
> > >  }
> > >
> > > -static int nftnl_expr_objref_snprintf(char *buf, size_t len, uint32_t type,
> > > +static int nftnl_expr_objref_snprintf(char *buf, size_t size, uint32_t type,
> > >  				      uint32_t flags,
> > >  				      const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_objref_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_objref_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_objref_export(buf, len, e, type);
> > > +		return nftnl_expr_objref_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/payload.c b/src/expr/payload.c
> > > index 897fc77..d61e854 100644
> > > --- a/src/expr/payload.c
> > > +++ b/src/expr/payload.c
> > > @@ -285,30 +285,30 @@ static int nftnl_expr_payload_export(char *buf, size_t size, uint32_t flags,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_payload_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_payload_snprintf(char *buf, size_t size, uint32_t type,
> > >  			    uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > >  	struct nftnl_expr_payload *payload = nftnl_expr_data(e);
> > >
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > >  		if (payload->sreg)
> > > -			return snprintf(buf, len, "write reg %u => %ub @ %s header + %u csum_type %u csum_off %u csum_flags 0x%x ",
> > > +			return snprintf(buf, size, "write reg %u => %ub @ %s header + %u csum_type %u csum_off %u csum_flags 0x%x ",
> > >  					payload->sreg,
> > >  					payload->len, base2str(payload->base),
> > >  					payload->offset, payload->csum_type,
> > >  					payload->csum_offset,
> > >  					payload->csum_flags);
> > >  		else
> > > -			return snprintf(buf, len, "load %ub @ %s header + %u => reg %u ",
> > > +			return snprintf(buf, size, "load %ub @ %s header + %u => reg %u ",
> > >  					payload->len, base2str(payload->base),
> > >  					payload->offset, payload->dreg);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_payload_export(buf, len, flags, e, type);
> > > +		return nftnl_expr_payload_export(buf, size, flags, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/queue.c b/src/expr/queue.c
> > > index e0fb785..acb42e9 100644
> > > --- a/src/expr/queue.c
> > > +++ b/src/expr/queue.c
> > > @@ -172,41 +172,41 @@ nftnl_expr_queue_json_parse(struct nftnl_expr *e, json_t *root,
> > >  #endif
> > >  }
> > >
> > > -static int nftnl_expr_queue_snprintf_default(char *buf, size_t len,
> > > +static int nftnl_expr_queue_snprintf_default(char *buf, size_t size,
> > >  					     const struct nftnl_expr *e)
> > >  {
> > >  	struct nftnl_expr_queue *queue = nftnl_expr_data(e);
> > > -	int ret, remain = len, offset = 0;
> > > +	int ret, remain = size, offset = 0;
> > >  	uint16_t total_queues;
> > >
> > >  	if (e->flags & (1 << NFTNL_EXPR_QUEUE_NUM)) {
> > >  		total_queues = queue->queuenum + queue->queues_total - 1;
> > >
> > > -		ret = snprintf(buf + offset, len, "num %u", queue->queuenum);
> > > +		ret = snprintf(buf + offset, size, "num %u", queue->queuenum);
> > >  		SNPRINTF_BUFFER_SIZE(ret, remain, offset);
> > >
> > >  		if (queue->queues_total && total_queues != queue->queuenum) {
> > > -			ret = snprintf(buf + offset, len, "-%u", total_queues);
> > > +			ret = snprintf(buf + offset, size, "-%u", total_queues);
> > >  			SNPRINTF_BUFFER_SIZE(ret, remain, offset);
> > >  		}
> > >
> > > -		ret = snprintf(buf + offset, len, " ");
> > > +		ret = snprintf(buf + offset, size, " ");
> > >  		SNPRINTF_BUFFER_SIZE(ret, remain, offset);
> > >  	}
> > >
> > >  	if (e->flags & (1 << NFTNL_EXPR_QUEUE_SREG_QNUM)) {
> > > -		ret = snprintf(buf + offset, len, "sreg_qnum %u ",
> > > +		ret = snprintf(buf + offset, size, "sreg_qnum %u ",
> > >  			       queue->sreg_qnum);
> > >  		SNPRINTF_BUFFER_SIZE(ret, remain, offset);
> > >  	}
> > >
> > >  	if (e->flags & (1 << NFTNL_EXPR_QUEUE_FLAGS)) {
> > >  		if (queue->flags & (NFT_QUEUE_FLAG_BYPASS)) {
> > > -			ret = snprintf(buf + offset, len, "bypass ");
> > > +			ret = snprintf(buf + offset, size, "bypass ");
> > >  			SNPRINTF_BUFFER_SIZE(ret, remain, offset);
> > >  		}
> > >  		if (queue->flags & (NFT_QUEUE_FLAG_CPU_FANOUT)) {
> > > -			ret = snprintf(buf + offset, len, "fanout ");
> > > +			ret = snprintf(buf + offset, size, "fanout ");
> > >  			SNPRINTF_BUFFER_SIZE(ret, remain, offset);
> > >  		}
> > >  	}
> > > @@ -232,18 +232,18 @@ static int nftnl_expr_queue_export(char *buf, size_t size,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_queue_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_queue_snprintf(char *buf, size_t size, uint32_t type,
> > >  			  uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_queue_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_queue_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_queue_export(buf, len, e, type);
> > > +		return nftnl_expr_queue_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/quota.c b/src/expr/quota.c
> > > index c247b0a..e9cc708 100644
> > > --- a/src/expr/quota.c
> > > +++ b/src/expr/quota.c
> > > @@ -169,29 +169,29 @@ static int nftnl_expr_quota_export(char *buf, size_t size,
> > >  	return nftnl_buf_done(&b);
> > >  }
> > >
> > > -static int nftnl_expr_quota_snprintf_default(char *buf, size_t len,
> > > +static int nftnl_expr_quota_snprintf_default(char *buf, size_t size,
> > >  					       const struct nftnl_expr *e)
> > >  {
> > >  	struct nftnl_expr_quota *quota = nftnl_expr_data(e);
> > >
> > > -	return snprintf(buf, len,
> > > +	return snprintf(buf, size,
> > >  			"bytes %"PRIu64" consumed %"PRIu64" flags %u ",
> > >  			quota->bytes, quota->consumed, quota->flags);
> > >  }
> > >
> > > -static int nftnl_expr_quota_snprintf(char *buf, size_t len, uint32_t type,
> > > +static int nftnl_expr_quota_snprintf(char *buf, size_t size, uint32_t type,
> > >  				       uint32_t flags,
> > >  				       const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_quota_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_quota_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_quota_export(buf, len, e, type);
> > > +		return nftnl_expr_quota_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/redir.c b/src/expr/redir.c
> > > index 9fb634a..b58635c 100644
> > > --- a/src/expr/redir.c
> > > +++ b/src/expr/redir.c
> > > @@ -173,26 +173,26 @@ static int nftnl_expr_redir_export(char *buf, size_t size,
> > >  	return nftnl_buf_done(&b);
> > >  }
> > >
> > > -static int nftnl_expr_redir_snprintf_default(char *buf, size_t len,
> > > +static int nftnl_expr_redir_snprintf_default(char *buf, size_t size,
> > >  					     const struct nftnl_expr *e)
> > >  {
> > > -	int ret, remain = len, offset = 0;
> > > +	int ret, remain = size, offset = 0;
> > >  	struct nftnl_expr_redir *redir = nftnl_expr_data(e);
> > >
> > >  	if (nftnl_expr_is_set(e, NFTNL_EXPR_REDIR_REG_PROTO_MIN)) {
> > > -		ret = snprintf(buf + offset, len, "proto_min reg %u ",
> > > +		ret = snprintf(buf + offset, size, "proto_min reg %u ",
> > >  			       redir->sreg_proto_min);
> > >  		SNPRINTF_BUFFER_SIZE(ret, remain, offset);
> > >  	}
> > >
> > >  	if (nftnl_expr_is_set(e, NFTNL_EXPR_REDIR_REG_PROTO_MAX)) {
> > > -		ret = snprintf(buf + offset, len, "proto_max reg %u ",
> > > +		ret = snprintf(buf + offset, size, "proto_max reg %u ",
> > >  			       redir->sreg_proto_max);
> > >  		SNPRINTF_BUFFER_SIZE(ret, remain, offset);
> > >  	}
> > >
> > >  	if (nftnl_expr_is_set(e, NFTNL_EXPR_REDIR_FLAGS)) {
> > > -		ret = snprintf(buf + offset, len, "flags 0x%x ",
> > > +		ret = snprintf(buf + offset, size, "flags 0x%x ",
> > >  			       redir->flags);
> > >  		SNPRINTF_BUFFER_SIZE(ret, remain, offset);
> > >  	}
> > > @@ -201,18 +201,18 @@ static int nftnl_expr_redir_snprintf_default(char *buf, size_t len,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_redir_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_redir_snprintf(char *buf, size_t size, uint32_t type,
> > >  			  uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_redir_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_redir_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_redir_export(buf, len, e, type);
> > > +		return nftnl_expr_redir_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/reject.c b/src/expr/reject.c
> > > index 1e6fdf5..01bafb4 100644
> > > --- a/src/expr/reject.c
> > > +++ b/src/expr/reject.c
> > > @@ -137,12 +137,12 @@ nftnl_expr_reject_json_parse(struct nftnl_expr *e, json_t *root,
> > >  #endif
> > >  }
> > >
> > > -static int nftnl_expr_reject_snprintf_default(char *buf, size_t len,
> > > +static int nftnl_expr_reject_snprintf_default(char *buf, size_t size,
> > >  					      const struct nftnl_expr *e)
> > >  {
> > >  	struct nftnl_expr_reject *reject = nftnl_expr_data(e);
> > >
> > > -	return snprintf(buf, len, "type %u code %u ",
> > > +	return snprintf(buf, size, "type %u code %u ",
> > >  			reject->type, reject->icmp_code);
> > >  }
> > >
> > > @@ -161,18 +161,18 @@ static int nftnl_expr_reject_export(char *buf, size_t size,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_reject_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_reject_snprintf(char *buf, size_t size, uint32_t type,
> > >  			   uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_reject_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_reject_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_reject_export(buf, len, e, type);
> > > +		return nftnl_expr_reject_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/rt.c b/src/expr/rt.c
> > > index 10cb1e2..408b9a9 100644
> > > --- a/src/expr/rt.c
> > > +++ b/src/expr/rt.c
> > > @@ -173,13 +173,13 @@ static int nftnl_expr_rt_json_parse(struct nftnl_expr *e, json_t *root,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_rt_snprintf_default(char *buf, size_t len,
> > > +nftnl_expr_rt_snprintf_default(char *buf, size_t size,
> > >  			       const struct nftnl_expr *e)
> > >  {
> > >  	struct nftnl_expr_rt *rt = nftnl_expr_data(e);
> > >
> > >  	if (e->flags & (1 << NFTNL_EXPR_RT_DREG)) {
> > > -		return snprintf(buf, len, "load %s => reg %u ",
> > > +		return snprintf(buf, size, "load %s => reg %u ",
> > >  				rt_key2str(rt->key), rt->dreg);
> > >  	}
> > >  	return 0;
> > > @@ -200,18 +200,18 @@ static int nftnl_expr_rt_export(char *buf, size_t size,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_rt_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_rt_snprintf(char *buf, size_t size, uint32_t type,
> > >  		       uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return nftnl_expr_rt_snprintf_default(buf, len, e);
> > > +		return nftnl_expr_rt_snprintf_default(buf, size, e);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_expr_rt_export(buf, len, e, type);
> > > +		return nftnl_expr_rt_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > diff --git a/src/expr/target.c b/src/expr/target.c
> > > index 3c58b03..524b378 100644
> > > --- a/src/expr/target.c
> > > +++ b/src/expr/target.c
> > > @@ -195,21 +195,21 @@ static int nftnl_rule_exp_target_export(char *buf, size_t size,
> > >  }
> > >
> > >  static int
> > > -nftnl_expr_target_snprintf(char *buf, size_t len, uint32_t type,
> > > +nftnl_expr_target_snprintf(char *buf, size_t size, uint32_t type,
> > >  			   uint32_t flags, const struct nftnl_expr *e)
> > >  {
> > >  	struct nftnl_expr_target *target = nftnl_expr_data(e);
> > >
> > > -	if (len)
> > > +	if (size)
> > >  		buf[0] = '\0';
> > >
> > >  	switch (type) {
> > >  	case NFTNL_OUTPUT_DEFAULT:
> > > -		return snprintf(buf, len, "name %s rev %u ",
> > > +		return snprintf(buf, size, "name %s rev %u ",
> > >  				target->name, target->rev);
> > >  	case NFTNL_OUTPUT_XML:
> > >  	case NFTNL_OUTPUT_JSON:
> > > -		return nftnl_rule_exp_target_export(buf, len, e, type);
> > > +		return nftnl_rule_exp_target_export(buf, size, e, type);
> > >  	default:
> > >  		break;
> > >  	}
> > > --
> > > 2.7.4
> > >
> > > --
> > > You received this message because you are subscribed to the Google Groups "outreachy-kernel" group.
> > > To unsubscribe from this group and stop receiving emails from it, send an email to outreachy-kernel+unsubscribe@googlegroups.com.
> > > To post to this group, send email to outreachy-kernel@googlegroups.com.
> > > To view this discussion on the web visit https://groups.google.com/d/msgid/outreachy-kernel/20171004182138.GA24970%40meghana-HP-Pavilion-Notebook.
> > > For more options, visit https://groups.google.com/d/optout.
> > >
>
> --
> You received this message because you are subscribed to the Google Groups "outreachy-kernel" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to outreachy-kernel+unsubscribe@googlegroups.com.
> To post to this group, send email to outreachy-kernel@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/outreachy-kernel/20171005032543.GA28390%40meghana-HP-Pavilion-Notebook.
> For more options, visit https://groups.google.com/d/optout.
>


^ permalink raw reply

* [qemu-upstream-4.6-testing test] 114018: tolerable FAIL - PUSHED
From: osstest service owner @ 2017-10-05  6:35 UTC (permalink / raw)
  To: xen-devel, osstest-admin

flight 114018 qemu-upstream-4.6-testing real [real]
http://logs.test-lab.xenproject.org/osstest/logs/114018/

Failures :-/ but no regressions.

Tests which did not succeed, but are not blocking:
 test-armhf-armhf-xl-rtds     16 guest-start/debian.repeat    fail  like 111045
 test-armhf-armhf-libvirt     14 saverestore-support-check    fail  like 111072
 test-armhf-armhf-libvirt-raw 13 saverestore-support-check    fail  like 111072
 test-armhf-armhf-libvirt-xsm 14 saverestore-support-check    fail  like 111072
 test-amd64-amd64-xl-qemuu-win7-amd64 17 guest-stop            fail like 111072
 test-amd64-i386-xl-qemuu-win7-amd64 17 guest-stop             fail like 111072
 test-amd64-i386-libvirt-xsm  13 migrate-support-check        fail   never pass
 test-amd64-amd64-libvirt     13 migrate-support-check        fail   never pass
 test-amd64-amd64-xl-pvh-amd  12 guest-start                  fail   never pass
 test-amd64-amd64-libvirt-vhd 12 migrate-support-check        fail   never pass
 test-amd64-amd64-xl-qemuu-ws16-amd64 10 windows-install        fail never pass
 test-amd64-amd64-libvirt-xsm 13 migrate-support-check        fail   never pass
 test-amd64-i386-libvirt      13 migrate-support-check        fail   never pass
 test-amd64-amd64-xl-pvh-intel 15 guest-saverestore            fail  never pass
 test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass
 test-armhf-armhf-xl-arndale  13 migrate-support-check        fail   never pass
 test-armhf-armhf-xl-multivcpu 13 migrate-support-check        fail  never pass
 test-armhf-armhf-xl-arndale  14 saverestore-support-check    fail   never pass
 test-armhf-armhf-xl-multivcpu 14 saverestore-support-check    fail  never pass
 test-armhf-armhf-libvirt     13 migrate-support-check        fail   never pass
 test-amd64-i386-libvirt-qcow2 12 migrate-support-check        fail  never pass
 test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass
 test-amd64-amd64-qemuu-nested-amd 17 debian-hvm-install/l1/l2  fail never pass
 test-armhf-armhf-xl-rtds     13 migrate-support-check        fail   never pass
 test-armhf-armhf-xl-rtds     14 saverestore-support-check    fail   never pass
 test-armhf-armhf-libvirt-raw 12 migrate-support-check        fail   never pass
 test-armhf-armhf-xl-xsm      13 migrate-support-check        fail   never pass
 test-armhf-armhf-xl-xsm      14 saverestore-support-check    fail   never pass
 test-armhf-armhf-xl-cubietruck 13 migrate-support-check        fail never pass
 test-armhf-armhf-xl          13 migrate-support-check        fail   never pass
 test-armhf-armhf-xl-cubietruck 14 saverestore-support-check    fail never pass
 test-armhf-armhf-xl          14 saverestore-support-check    fail   never pass
 test-armhf-armhf-libvirt-xsm 13 migrate-support-check        fail   never pass
 test-armhf-armhf-xl-credit2  13 migrate-support-check        fail   never pass
 test-armhf-armhf-xl-credit2  14 saverestore-support-check    fail   never pass
 test-amd64-i386-xl-qemuu-ws16-amd64 13 guest-saverestore       fail never pass
 test-armhf-armhf-xl-vhd      12 migrate-support-check        fail   never pass
 test-armhf-armhf-xl-vhd      13 saverestore-support-check    fail   never pass
 test-amd64-amd64-xl-qemuu-win10-i386 10 windows-install        fail never pass
 test-amd64-i386-xl-qemuu-win10-i386 10 windows-install         fail never pass

version targeted for testing:
 qemuu                9e879690ecc702c271fda4cb48663bb83fdf1832
baseline version:
 qemuu                4e35ab1edd74b7d24b7a4aaebe75fe68222a2f2b

Last test of basis   111072  2017-06-26 14:25:40 Z  100 days
Testing same since   114018  2017-10-04 18:45:52 Z    0 days    1 attempts

------------------------------------------------------------
People who touched revisions under test:
  Gerd Hoffmann <kraxel@redhat.com>
  Stefano Stabellini <sstabellini@kernel.org>

jobs:
 build-amd64-xsm                                              pass    
 build-armhf-xsm                                              pass    
 build-i386-xsm                                               pass    
 build-amd64                                                  pass    
 build-armhf                                                  pass    
 build-i386                                                   pass    
 build-amd64-libvirt                                          pass    
 build-armhf-libvirt                                          pass    
 build-i386-libvirt                                           pass    
 build-amd64-pvops                                            pass    
 build-armhf-pvops                                            pass    
 build-i386-pvops                                             pass    
 test-amd64-amd64-xl                                          pass    
 test-armhf-armhf-xl                                          pass    
 test-amd64-i386-xl                                           pass    
 test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm           pass    
 test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm            pass    
 test-amd64-amd64-xl-qemuu-debianhvm-amd64-xsm                pass    
 test-amd64-i386-xl-qemuu-debianhvm-amd64-xsm                 pass    
 test-amd64-amd64-libvirt-xsm                                 pass    
 test-armhf-armhf-libvirt-xsm                                 pass    
 test-amd64-i386-libvirt-xsm                                  pass    
 test-amd64-amd64-xl-xsm                                      pass    
 test-armhf-armhf-xl-xsm                                      pass    
 test-amd64-i386-xl-xsm                                       pass    
 test-amd64-amd64-qemuu-nested-amd                            fail    
 test-amd64-amd64-xl-pvh-amd                                  fail    
 test-amd64-i386-qemuu-rhel6hvm-amd                           pass    
 test-amd64-amd64-xl-qemuu-debianhvm-amd64                    pass    
 test-amd64-i386-xl-qemuu-debianhvm-amd64                     pass    
 test-amd64-i386-freebsd10-amd64                              pass    
 test-amd64-amd64-xl-qemuu-ovmf-amd64                         pass    
 test-amd64-i386-xl-qemuu-ovmf-amd64                          pass    
 test-amd64-amd64-xl-qemuu-win7-amd64                         fail    
 test-amd64-i386-xl-qemuu-win7-amd64                          fail    
 test-amd64-amd64-xl-qemuu-ws16-amd64                         fail    
 test-amd64-i386-xl-qemuu-ws16-amd64                          fail    
 test-armhf-armhf-xl-arndale                                  pass    
 test-amd64-amd64-xl-credit2                                  pass    
 test-armhf-armhf-xl-credit2                                  pass    
 test-armhf-armhf-xl-cubietruck                               pass    
 test-amd64-i386-freebsd10-i386                               pass    
 test-amd64-amd64-xl-qemuu-win10-i386                         fail    
 test-amd64-i386-xl-qemuu-win10-i386                          fail    
 test-amd64-amd64-qemuu-nested-intel                          pass    
 test-amd64-amd64-xl-pvh-intel                                fail    
 test-amd64-i386-qemuu-rhel6hvm-intel                         pass    
 test-amd64-amd64-libvirt                                     pass    
 test-armhf-armhf-libvirt                                     pass    
 test-amd64-i386-libvirt                                      pass    
 test-amd64-amd64-xl-multivcpu                                pass    
 test-armhf-armhf-xl-multivcpu                                pass    
 test-amd64-amd64-pair                                        pass    
 test-amd64-i386-pair                                         pass    
 test-amd64-amd64-libvirt-pair                                pass    
 test-amd64-i386-libvirt-pair                                 pass    
 test-amd64-amd64-amd64-pvgrub                                pass    
 test-amd64-amd64-i386-pvgrub                                 pass    
 test-amd64-amd64-pygrub                                      pass    
 test-amd64-i386-libvirt-qcow2                                pass    
 test-amd64-amd64-xl-qcow2                                    pass    
 test-armhf-armhf-libvirt-raw                                 pass    
 test-amd64-i386-xl-raw                                       pass    
 test-amd64-amd64-xl-rtds                                     pass    
 test-armhf-armhf-xl-rtds                                     fail    
 test-amd64-amd64-libvirt-vhd                                 pass    
 test-armhf-armhf-xl-vhd                                      pass    


------------------------------------------------------------
sg-report-flight on osstest.test-lab.xenproject.org
logs: /home/logs/logs
images: /home/logs/images

Logs, config files, etc. are available at
    http://logs.test-lab.xenproject.org/osstest/logs

Explanation of these reports, and of osstest in general, is at
    http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README.email;hb=master
    http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README;hb=master

Test harness code can be found at
    http://xenbits.xen.org/gitweb?p=osstest.git;a=summary


Pushing revision :

+ branch=qemu-upstream-4.6-testing
+ revision=9e879690ecc702c271fda4cb48663bb83fdf1832
+ . ./cri-lock-repos
++ . ./cri-common
+++ . ./cri-getconfig
++++ export PERLLIB=.:.
++++ PERLLIB=.:.
+++ umask 002
+++ getrepos
++++ getconfig Repos
++++ perl -e '
                use Osstest;
                readglobalconfig();
                print $c{"Repos"} or die $!;
        '
+++ local repos=/home/osstest/repos
+++ '[' -z /home/osstest/repos ']'
+++ '[' '!' -d /home/osstest/repos ']'
+++ echo /home/osstest/repos
++ repos=/home/osstest/repos
++ repos_lock=/home/osstest/repos/lock
++ '[' x '!=' x/home/osstest/repos/lock ']'
++ OSSTEST_REPOS_LOCK_LOCKED=/home/osstest/repos/lock
++ exec with-lock-ex -w /home/osstest/repos/lock ./ap-push qemu-upstream-4.6-testing 9e879690ecc702c271fda4cb48663bb83fdf1832
+ branch=qemu-upstream-4.6-testing
+ revision=9e879690ecc702c271fda4cb48663bb83fdf1832
+ . ./cri-lock-repos
++ . ./cri-common
+++ . ./cri-getconfig
++++ export PERLLIB=.:.:.
++++ PERLLIB=.:.:.
+++ umask 002
+++ getrepos
++++ getconfig Repos
++++ perl -e '
                use Osstest;
                readglobalconfig();
                print $c{"Repos"} or die $!;
        '
+++ local repos=/home/osstest/repos
+++ '[' -z /home/osstest/repos ']'
+++ '[' '!' -d /home/osstest/repos ']'
+++ echo /home/osstest/repos
++ repos=/home/osstest/repos
++ repos_lock=/home/osstest/repos/lock
++ '[' x/home/osstest/repos/lock '!=' x/home/osstest/repos/lock ']'
+ . ./cri-common
++ . ./cri-getconfig
+++ export PERLLIB=.:.:.:.
+++ PERLLIB=.:.:.:.
++ umask 002
+ select_xenbranch
+ case "$branch" in
+ tree=qemuu
+ xenbranch=xen-4.6-testing
+ '[' xqemuu = xlinux ']'
+ linuxbranch=
+ '[' x = x ']'
+ qemuubranch=qemu-upstream-4.6-testing
+ select_prevxenbranch
++ ./cri-getprevxenbranch xen-4.6-testing
+ prevxenbranch=xen-4.5-testing
+ '[' x9e879690ecc702c271fda4cb48663bb83fdf1832 = x ']'
+ : tested/2.6.39.x
+ . ./ap-common
++ : osstest@xenbits.xen.org
+++ getconfig OsstestUpstream
+++ perl -e '
                use Osstest;
                readglobalconfig();
                print $c{"OsstestUpstream"} or die $!;
        '
++ :
++ : git://xenbits.xen.org/xen.git
++ : osstest@xenbits.xen.org:/home/xen/git/xen.git
++ : git://xenbits.xen.org/qemu-xen-traditional.git
++ : git://git.kernel.org
++ : git://git.kernel.org/pub/scm/linux/kernel/git
++ : git
++ : git://xenbits.xen.org/xtf.git
++ : osstest@xenbits.xen.org:/home/xen/git/xtf.git
++ : git://xenbits.xen.org/xtf.git
++ : git://xenbits.xen.org/libvirt.git
++ : osstest@xenbits.xen.org:/home/xen/git/libvirt.git
++ : git://xenbits.xen.org/libvirt.git
++ : git://xenbits.xen.org/osstest/rumprun.git
++ : git
++ : git://xenbits.xen.org/osstest/rumprun.git
++ : osstest@xenbits.xen.org:/home/xen/git/osstest/rumprun.git
++ : git://git.seabios.org/seabios.git
++ : osstest@xenbits.xen.org:/home/xen/git/osstest/seabios.git
++ : git://xenbits.xen.org/osstest/seabios.git
++ : https://github.com/tianocore/edk2.git
++ : osstest@xenbits.xen.org:/home/xen/git/osstest/ovmf.git
++ : git://xenbits.xen.org/osstest/ovmf.git
++ : git://xenbits.xen.org/osstest/linux-firmware.git
++ : osstest@xenbits.xen.org:/home/osstest/ext/linux-firmware.git
++ : git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
++ : osstest@xenbits.xen.org:/home/xen/git/linux-pvops.git
++ : git://xenbits.xen.org/linux-pvops.git
++ : tested/linux-4.9
++ : tested/linux-arm-xen
++ '[' xgit://xenbits.xen.org/linux-pvops.git = x ']'
++ '[' x = x ']'
++ : git://xenbits.xen.org/linux-pvops.git
++ : tested/linux-arm-xen
++ : git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen.git
++ : tested/2.6.39.x
++ : daily-cron.qemu-upstream-4.6-testing
++ : daily-cron.qemu-upstream-4.6-testing
++ : daily-cron.qemu-upstream-4.6-testing
++ : daily-cron.qemu-upstream-4.6-testing
++ : daily-cron.qemu-upstream-4.6-testing
++ : daily-cron.qemu-upstream-4.6-testing
++ : daily-cron.qemu-upstream-4.6-testing
++ : http://hg.uk.xensource.com/carbon/trunk/linux-2.6.27
++ : git://xenbits.xen.org/qemu-xen.git
++ : osstest@xenbits.xen.org:/home/xen/git/qemu-xen.git
++ : daily-cron.qemu-upstream-4.6-testing
++ : git://xenbits.xen.org/qemu-xen.git
++ : git://git.qemu.org/qemu.git
+ TREE_LINUX=osstest@xenbits.xen.org:/home/xen/git/linux-pvops.git
+ TREE_QEMU_UPSTREAM=osstest@xenbits.xen.org:/home/xen/git/qemu-xen.git
+ TREE_XEN=osstest@xenbits.xen.org:/home/xen/git/xen.git
+ TREE_LIBVIRT=osstest@xenbits.xen.org:/home/xen/git/libvirt.git
+ TREE_RUMPRUN=osstest@xenbits.xen.org:/home/xen/git/osstest/rumprun.git
+ TREE_SEABIOS=osstest@xenbits.xen.org:/home/xen/git/osstest/seabios.git
+ TREE_OVMF=osstest@xenbits.xen.org:/home/xen/git/osstest/ovmf.git
+ TREE_XTF=osstest@xenbits.xen.org:/home/xen/git/xtf.git
+ info_linux_tree qemu-upstream-4.6-testing
+ case $1 in
+ return 1
+ case "$branch" in
+ branchcore=4.6-testing
+ branchcore=4.6
+ cd /home/osstest/repos/qemu-upstream-4.6-testing
+ git push osstest@xenbits.xen.org:/home/xen/git/qemu-xen.git 9e879690ecc702c271fda4cb48663bb83fdf1832:refs/heads/stable-4.6
To osstest@xenbits.xen.org:/home/xen/git/qemu-xen.git
   4e35ab1..9e87969  9e879690ecc702c271fda4cb48663bb83fdf1832 -> stable-4.6
+ case "$branchcore" in
+ tree=osstest@xenbits.xen.org:/home/xen/git/qemu-upstream-4.6-testing.git
+ git push osstest@xenbits.xen.org:/home/xen/git/qemu-upstream-4.6-testing.git 9e879690ecc702c271fda4cb48663bb83fdf1832:refs/heads/master
To osstest@xenbits.xen.org:/home/xen/git/qemu-upstream-4.6-testing.git
   4e35ab1..9e87969  9e879690ecc702c271fda4cb48663bb83fdf1832 -> master

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply

* [PATCH] soc: mediatek: turn MTK_PMIC_WRAP into visible symbols
From: Sean Wang @ 2017-10-05  6:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAK8P3a3WPPQrLL0r2FSBms-9UxFFQTkBs7kBaCQRkqX5Ohv36g@mail.gmail.com>

On Mon, 2017-10-02 at 13:21 +0200, Arnd Bergmann wrote:
> On Tue, Sep 26, 2017 at 8:00 AM, Jean Delvare <jdelvare@suse.de> wrote:
> > On Thu, 21 Sep 2017 17:01:05 +0800, sean.wang at mediatek.com wrote:
> >> From: Sean Wang <sean.wang@mediatek.com>
> >>
> >> MTK_PMIC_WRAP is the basic and required configuration for those various
> >> MediaTek PMICs, so turning MTK_PMIC_WRAP into visible symbols easily
> >> allows users tending to have the enablement for those PMICs.
> >
> > I can't really make sense of the sentence above, sorry, and can't see
> > how it matches the change below anyway. MTK_PMIC_WRAP is already a
> > visible symbol before this change. The change is probably good in
> > itself, but please try to come up with a better description.
> >
> >> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
> >> ---
> >>  drivers/soc/mediatek/Kconfig | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> >> index a2fcd7f..d513629 100644
> >> --- a/drivers/soc/mediatek/Kconfig
> >> +++ b/drivers/soc/mediatek/Kconfig
> >> @@ -15,7 +15,7 @@ config MTK_INFRACFG
> >>  config MTK_PMIC_WRAP
> >>       tristate "MediaTek PMIC Wrapper Support"
> >>       depends on ARCH_MEDIATEK
> >> -     depends on RESET_CONTROLLER
> >> +     select RESET_CONTROLLER
> >>       select REGMAP
> 
> Your other patch now removes the ARCH_MEDIATEK dependency
> and allows enabling the driver for COMPILE_TEST on architectures
> that might not have ARCH_HAS_RESET_CONTROLLER set,
> so you cannot 'select' the symbol in general.
> 
> I think a better solution is to leave the 'depends on
> RESET_CONTROLLER' present here, but instead add
> 'select RESET_CONTROLLER' to the ARCH_MEDIATEK
> definition.
> 
> Generally speaking, we don't want to mix 'select' and 'depends on'
> statements for the same symbol, but if we do, it should be done
> consistently in a very clear hierarchy. In case of RESET_CONTROLLER,
> the rule seems to be to 'select' it from architectures and platforms,
> while using 'depends on' from device drivers that absolutely require it.
> 
> Note that for compile-testing, it should be fine to rely on the fallback
> definitions in include/linux/reset.h, so you might be able to just
> remove the 'depends on' statement completely.
> 
> In any case, please try to be clearer about what the patch
> actually tries to achieve. Did you run into a build error without
> it? If so, please copy the exact build error message into the
> patch description.
> 
>       Arnd

Thanks for your both suggestions and idea

No any compile error is present prior to the patch.

In the initial thought, I simply would like to allow the configuration
item able to be visible in menuconfig without visiting all dependencies
for it, especially for those SoC-required drivers when the corresponding
architecture target is already picked up.

I prefer to the better solution leaving 'depends on RESET_CONTROLLER'
present here, and add additional 'select ARCH_RESET_CONTROLLER' to the
ARCH_MEDIATEK definition, which could reach the goal initially I'd try
to. So I will update them in this way in the next version, including a
better description of the patch.

	Sean 

^ permalink raw reply

* Re: [PATCH] soc: mediatek: turn MTK_PMIC_WRAP into visible symbols
From: Sean Wang @ 2017-10-05  6:33 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Jean Delvare, Matthias Brugger,
	moderated list:ARM/Mediatek SoC..., Linux ARM,
	Linux Kernel Mailing List
In-Reply-To: <CAK8P3a3WPPQrLL0r2FSBms-9UxFFQTkBs7kBaCQRkqX5Ohv36g@mail.gmail.com>

On Mon, 2017-10-02 at 13:21 +0200, Arnd Bergmann wrote:
> On Tue, Sep 26, 2017 at 8:00 AM, Jean Delvare <jdelvare@suse.de> wrote:
> > On Thu, 21 Sep 2017 17:01:05 +0800, sean.wang@mediatek.com wrote:
> >> From: Sean Wang <sean.wang@mediatek.com>
> >>
> >> MTK_PMIC_WRAP is the basic and required configuration for those various
> >> MediaTek PMICs, so turning MTK_PMIC_WRAP into visible symbols easily
> >> allows users tending to have the enablement for those PMICs.
> >
> > I can't really make sense of the sentence above, sorry, and can't see
> > how it matches the change below anyway. MTK_PMIC_WRAP is already a
> > visible symbol before this change. The change is probably good in
> > itself, but please try to come up with a better description.
> >
> >> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
> >> ---
> >>  drivers/soc/mediatek/Kconfig | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> >> index a2fcd7f..d513629 100644
> >> --- a/drivers/soc/mediatek/Kconfig
> >> +++ b/drivers/soc/mediatek/Kconfig
> >> @@ -15,7 +15,7 @@ config MTK_INFRACFG
> >>  config MTK_PMIC_WRAP
> >>       tristate "MediaTek PMIC Wrapper Support"
> >>       depends on ARCH_MEDIATEK
> >> -     depends on RESET_CONTROLLER
> >> +     select RESET_CONTROLLER
> >>       select REGMAP
> 
> Your other patch now removes the ARCH_MEDIATEK dependency
> and allows enabling the driver for COMPILE_TEST on architectures
> that might not have ARCH_HAS_RESET_CONTROLLER set,
> so you cannot 'select' the symbol in general.
> 
> I think a better solution is to leave the 'depends on
> RESET_CONTROLLER' present here, but instead add
> 'select RESET_CONTROLLER' to the ARCH_MEDIATEK
> definition.
> 
> Generally speaking, we don't want to mix 'select' and 'depends on'
> statements for the same symbol, but if we do, it should be done
> consistently in a very clear hierarchy. In case of RESET_CONTROLLER,
> the rule seems to be to 'select' it from architectures and platforms,
> while using 'depends on' from device drivers that absolutely require it.
> 
> Note that for compile-testing, it should be fine to rely on the fallback
> definitions in include/linux/reset.h, so you might be able to just
> remove the 'depends on' statement completely.
> 
> In any case, please try to be clearer about what the patch
> actually tries to achieve. Did you run into a build error without
> it? If so, please copy the exact build error message into the
> patch description.
> 
>       Arnd

Thanks for your both suggestions and idea

No any compile error is present prior to the patch.

In the initial thought, I simply would like to allow the configuration
item able to be visible in menuconfig without visiting all dependencies
for it, especially for those SoC-required drivers when the corresponding
architecture target is already picked up.

I prefer to the better solution leaving 'depends on RESET_CONTROLLER'
present here, and add additional 'select ARCH_RESET_CONTROLLER' to the
ARCH_MEDIATEK definition, which could reach the goal initially I'd try
to. So I will update them in this way in the next version, including a
better description of the patch.

	Sean 

^ permalink raw reply

* [linux-next][DLPAR CPU][Oops] Kernel crash with CPU hotunplug
From: Abdul Haleem @ 2017-10-05  6:33 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: linux-next, linux-kernel, Michael Ellerman, Rob Herring,
	Tyrel Datwyler, sachinp

Hi,

linux-next kernel panic while DLPAR CPU add/remove operation in a loop.

Test: CPU hot-unplug
Machine Type: Power8 PowerVM LPAR
kernel: 4.14.0-rc2-next-20170928
gcc : 5.2.1

trace logs
----------
cpu 10 (hwid 10) Ready to die...
cpu 11 (hwid 11) Ready to die...
cpu 12 (hwid 12) Ready to die...
cpu 13 (hwid 13) Ready to die...
cpu 14 (hwid 14) Ready to die...
cpu 15 (hwid 15) Ready to die...
Unable to handle kernel paging request for data at address 0xdead4ead00000030
Faulting instruction address: 0xc000000001af38e4
Oops: Kernel access of bad area, sig: 11 [#1]
LE SMP NR_CPUS=2048 NUMA pSeries
Modules linked in: rpadlpar_io rpaphp bridge stp llc xt_tcpudp ipt_REJECT nf_reject_ipv4 xt_conntrack nfnetlink iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_filter vmx_crypto pseries_rng rng_core binfmt_misc nfsd ip_tables x_tables autofs4
CPU: 7 PID: 10657 Comm: systemd-udevd Not tainted 4.14.0-rc2-next-20170928-autotest #1
task: c000000271b7cc00 task.stack: c00000026d504000
NIP:  c000000001af38e4 LR: c000000001af3b48 CTR: c000000001af4270
REGS: c00000026d5079e0 TRAP: 0380   Not tainted  (4.14.0-rc2-next-20170928-autotest)
MSR:  8000000000009033 <SF,EE,ME,IR,DR,RI,LE>  CR: 22008882  XER: 20000000  
CFAR: c000000001af3b44 SOFTE: 1 
GPR00: c000000001af3b48 c00000026d507c60 c000000003572500 c00000026c0d4a80 
GPR04: c00000026c0d4a80 c00000026b56b310 c0000000037d2500 dead4ead00000030 
GPR08: 00000000000016f0 fffffffffffffff0 dead4ead00000000 c000000270b24420 
GPR12: c000000001af4270 c00000000fdc1f80 00000000000029a3 000000000aba9500 
GPR16: 000001000e4134f0 000000000aba9500 000000000000000f 0000000000000001 
GPR20: 0000000120ff68d8 0000000120ff68d0 0000000120ff6a48 0000000120ff33f0 
GPR24: 0000000120ff6550 c00000026b56b310 c00000027286d9b8 c0000000037d4d88 
GPR28: c0000002727b17a0 c00000026c0d4a80 c00000027286da38 c00000026c0d4a80 
NIP [c000000001af38e4] free_pipe_info+0x64/0x200
LR [c000000001af3b48] put_pipe_info+0xc8/0x140
Call Trace:
[c00000026d507c60] [c00000027286da38] 0xc00000027286da38 (unreliable)
[c00000026d507ca0] [c000000001af3b48] put_pipe_info+0xc8/0x140
[c00000026d507ce0] [c000000001af43fc] pipe_release+0x18c/0x1e0
[c00000026d507d20] [c000000001ae0efc] __fput+0x12c/0x4f0
[c00000026d507d80] [c000000001ae12ec] ____fput+0x2c/0x50
[c00000026d507da0] [c00000000178eb3c] task_work_run+0x17c/0x200
[c00000026d507e00] [c00000000160adb8] do_notify_resume+0x1f8/0x220
[c00000026d507e30] [c0000000015ebec4] ret_from_except_lite+0x70/0x74
Instruction dump:
81230070 e94300b0 39080001 7d2900d0 38ea0030 f9066d98 7c0004ac 3d020026 
e9086da0 3cc20026 39080001 f9066da0 <7d0038a8> 7d094214 7d0039ad 40c2fff4 
---[ end trace 4dcb6f2341ddb370 ]---

Kernel panic - not syncing: Fatal exception
Rebooting in 10 seconds..

Test logs:
----------
DLPAR remove cpu operation
Running 'drmgr -c cpu -d 5 -w 30 -r'

########## Oct 04 03:09:22 2017 ##########
drmgr: -c cpu -d 5 -w 30 -r
Validating CPU DLPAR capability...yes.
Expecting 20 threads...found 16.
Found cpu PowerPC,POWER8@8
Found cpu PowerPC,POWER8@0
Start CPU List.
10000008 : CPU 9
    thread: 8: /sys/devices/system/cpu/cpu8
    thread: 9: /sys/devices/system/cpu/cpu9
    thread: 10: /sys/devices/system/cpu/cpu10
    thread: 11: /sys/devices/system/cpu/cpu11
    thread: 12: /sys/devices/system/cpu/cpu12
    thread: 13: /sys/devices/system/cpu/cpu13
    thread: 14: /sys/devices/system/cpu/cpu14
    thread: 15: /sys/devices/system/cpu/cpu15
10000000 : CPU 1
    thread: 0: /sys/devices/system/cpu/cpu0
    thread: 1: /sys/devices/system/cpu/cpu1
    thread: 2: /sys/devices/system/cpu/cpu2
    thread: 3: /sys/devices/system/cpu/cpu3
    thread: 4: /sys/devices/system/cpu/cpu4
    thread: 5: /sys/devices/system/cpu/cpu5
    thread: 6: /sys/devices/system/cpu/cpu6
    thread: 7: /sys/devices/system/cpu/cpu7
Done.
Number of CPUs = 2
Releasing cpu "/cpus/PowerPC,POWER8@8"
Removed 1 of 1 requested cpu(s)
########## Oct 04 03:09:24 2017 ##########
Command 'drmgr -c cpu -d 5 -w 30 -r' finished with 0 after
2.20577907562s
[stdout] CPU 9
DLPAR add cpu operation
Running 'drmgr -c cpu -d 5 -w 30 -a'

########## Oct 04 03:09:24 2017 ##########
drmgr: -c cpu -d 5 -w 30 -a
Validating CPU DLPAR capability...yes.
Expecting 20 threads...found 16.
Found cpu PowerPC,POWER8@0
Start CPU List.
10000008 : CPU 9
10000000 : CPU 1
    thread: 0: /sys/devices/system/cpu/cpu0
    thread: 1: /sys/devices/system/cpu/cpu1
    thread: 2: /sys/devices/system/cpu/cpu2
    thread: 3: /sys/devices/system/cpu/cpu3
    thread: 4: /sys/devices/system/cpu/cpu4
    thread: 5: /sys/devices/system/cpu/cpu5
    thread: 6: /sys/devices/system/cpu/cpu6
    thread: 7: /sys/devices/system/cpu/cpu7
Done.
Probing cpu 0x10000008

Kernel panics after above operation.

-- 
Regard's

Abdul Haleem
IBM Linux Technology Centre

^ permalink raw reply

* [DLPAR CPU][Oops] Kernel crash with CPU hotunplug
From: Abdul Haleem @ 2017-10-05  6:33 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: linux-next, linux-kernel, Michael Ellerman, Rob Herring,
	Tyrel Datwyler, sachinp

Hi,

linux-next kernel panic while DLPAR CPU add/remove operation in a loop.

Test: CPU hot-unplug
Machine Type: Power8 PowerVM LPAR
kernel: 4.14.0-rc2-next-20170928
gcc : 5.2.1

trace logs
----------
cpu 10 (hwid 10) Ready to die...
cpu 11 (hwid 11) Ready to die...
cpu 12 (hwid 12) Ready to die...
cpu 13 (hwid 13) Ready to die...
cpu 14 (hwid 14) Ready to die...
cpu 15 (hwid 15) Ready to die...
Unable to handle kernel paging request for data at address 0xdead4ead00000030
Faulting instruction address: 0xc000000001af38e4
Oops: Kernel access of bad area, sig: 11 [#1]
LE SMP NR_CPUS=2048 NUMA pSeries
Modules linked in: rpadlpar_io rpaphp bridge stp llc xt_tcpudp ipt_REJECT nf_reject_ipv4 xt_conntrack nfnetlink iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_filter vmx_crypto pseries_rng rng_core binfmt_misc nfsd ip_tables x_tables autofs4
CPU: 7 PID: 10657 Comm: systemd-udevd Not tainted 4.14.0-rc2-next-20170928-autotest #1
task: c000000271b7cc00 task.stack: c00000026d504000
NIP:  c000000001af38e4 LR: c000000001af3b48 CTR: c000000001af4270
REGS: c00000026d5079e0 TRAP: 0380   Not tainted  (4.14.0-rc2-next-20170928-autotest)
MSR:  8000000000009033 <SF,EE,ME,IR,DR,RI,LE>  CR: 22008882  XER: 20000000  
CFAR: c000000001af3b44 SOFTE: 1 
GPR00: c000000001af3b48 c00000026d507c60 c000000003572500 c00000026c0d4a80 
GPR04: c00000026c0d4a80 c00000026b56b310 c0000000037d2500 dead4ead00000030 
GPR08: 00000000000016f0 fffffffffffffff0 dead4ead00000000 c000000270b24420 
GPR12: c000000001af4270 c00000000fdc1f80 00000000000029a3 000000000aba9500 
GPR16: 000001000e4134f0 000000000aba9500 000000000000000f 0000000000000001 
GPR20: 0000000120ff68d8 0000000120ff68d0 0000000120ff6a48 0000000120ff33f0 
GPR24: 0000000120ff6550 c00000026b56b310 c00000027286d9b8 c0000000037d4d88 
GPR28: c0000002727b17a0 c00000026c0d4a80 c00000027286da38 c00000026c0d4a80 
NIP [c000000001af38e4] free_pipe_info+0x64/0x200
LR [c000000001af3b48] put_pipe_info+0xc8/0x140
Call Trace:
[c00000026d507c60] [c00000027286da38] 0xc00000027286da38 (unreliable)
[c00000026d507ca0] [c000000001af3b48] put_pipe_info+0xc8/0x140
[c00000026d507ce0] [c000000001af43fc] pipe_release+0x18c/0x1e0
[c00000026d507d20] [c000000001ae0efc] __fput+0x12c/0x4f0
[c00000026d507d80] [c000000001ae12ec] ____fput+0x2c/0x50
[c00000026d507da0] [c00000000178eb3c] task_work_run+0x17c/0x200
[c00000026d507e00] [c00000000160adb8] do_notify_resume+0x1f8/0x220
[c00000026d507e30] [c0000000015ebec4] ret_from_except_lite+0x70/0x74
Instruction dump:
81230070 e94300b0 39080001 7d2900d0 38ea0030 f9066d98 7c0004ac 3d020026 
e9086da0 3cc20026 39080001 f9066da0 <7d0038a8> 7d094214 7d0039ad 40c2fff4 
---[ end trace 4dcb6f2341ddb370 ]---

Kernel panic - not syncing: Fatal exception
Rebooting in 10 seconds..

Test logs:
----------
DLPAR remove cpu operation
Running 'drmgr -c cpu -d 5 -w 30 -r'

########## Oct 04 03:09:22 2017 ##########
drmgr: -c cpu -d 5 -w 30 -r
Validating CPU DLPAR capability...yes.
Expecting 20 threads...found 16.
Found cpu PowerPC,POWER8@8
Found cpu PowerPC,POWER8@0
Start CPU List.
10000008 : CPU 9
    thread: 8: /sys/devices/system/cpu/cpu8
    thread: 9: /sys/devices/system/cpu/cpu9
    thread: 10: /sys/devices/system/cpu/cpu10
    thread: 11: /sys/devices/system/cpu/cpu11
    thread: 12: /sys/devices/system/cpu/cpu12
    thread: 13: /sys/devices/system/cpu/cpu13
    thread: 14: /sys/devices/system/cpu/cpu14
    thread: 15: /sys/devices/system/cpu/cpu15
10000000 : CPU 1
    thread: 0: /sys/devices/system/cpu/cpu0
    thread: 1: /sys/devices/system/cpu/cpu1
    thread: 2: /sys/devices/system/cpu/cpu2
    thread: 3: /sys/devices/system/cpu/cpu3
    thread: 4: /sys/devices/system/cpu/cpu4
    thread: 5: /sys/devices/system/cpu/cpu5
    thread: 6: /sys/devices/system/cpu/cpu6
    thread: 7: /sys/devices/system/cpu/cpu7
Done.
Number of CPUs = 2
Releasing cpu "/cpus/PowerPC,POWER8@8"
Removed 1 of 1 requested cpu(s)
########## Oct 04 03:09:24 2017 ##########
Command 'drmgr -c cpu -d 5 -w 30 -r' finished with 0 after
2.20577907562s
[stdout] CPU 9
DLPAR add cpu operation
Running 'drmgr -c cpu -d 5 -w 30 -a'

########## Oct 04 03:09:24 2017 ##########
drmgr: -c cpu -d 5 -w 30 -a
Validating CPU DLPAR capability...yes.
Expecting 20 threads...found 16.
Found cpu PowerPC,POWER8@0
Start CPU List.
10000008 : CPU 9
10000000 : CPU 1
    thread: 0: /sys/devices/system/cpu/cpu0
    thread: 1: /sys/devices/system/cpu/cpu1
    thread: 2: /sys/devices/system/cpu/cpu2
    thread: 3: /sys/devices/system/cpu/cpu3
    thread: 4: /sys/devices/system/cpu/cpu4
    thread: 5: /sys/devices/system/cpu/cpu5
    thread: 6: /sys/devices/system/cpu/cpu6
    thread: 7: /sys/devices/system/cpu/cpu7
Done.
Probing cpu 0x10000008

Kernel panics after above operation.

-- 
Regard's

Abdul Haleem
IBM Linux Technology Centre

^ permalink raw reply

* [Buildroot] [autobuild.buildroot.net] Build results for 2017-10-04
From: Thomas Petazzoni @ 2017-10-05  6:30 UTC (permalink / raw)
  To: buildroot

Hello,

Build statistics for 2017-10-04
================================

      successes : 197
       failures : 53 
       timeouts : 1  
          TOTAL : 251

Classification of failures by reason
====================================

      host-uboot-tools-2017.07 | 7 
host-vboot-utils-bbdd62f9b0... | 5 
                 mesa3d-17.2.2 | 5 
        wireguard-0.0.20171001 | 5 
                   cmake-3.8.2 | 4 
                    flex-2.6.4 | 3 
                host-mtd-2.0.1 | 3 
                openjpeg-2.2.0 | 3 
             dbus-python-1.2.4 | 2 
                   evemu-2.7.0 | 2 
host-squashfs-3de1687d7432e... | 2 
                   perl-5.26.1 | 2 
                  boost-1.64.0 | 1 
              ghostscript-9.21 | 1 
                   luvi-v2.7.6 | 1 
         mesa3d-headers-17.2.2 | 1 
                   mp4v2-2.0.0 | 1 
                     nmap-7.60 | 1 
                pinentry-1.0.0 | 1 
                      qt-4.8.7 | 1 
                 qt5base-5.6.2 | 1 
                    sdl2-2.0.6 | 1 
     toolchain-external-custom | 1 


Detail of failures
===================

     powerpc |                   boost-1.64.0 | NOK | http://autobuild.buildroot.net/results/c89265361ffb11bb4250aee9f4326a5955b419d5 |     
     powerpc |                    cmake-3.8.2 | NOK | http://autobuild.buildroot.net/results/6d4ca1c83ca01395c6691344268ad610ef44a6ae |     
     aarch64 |                    cmake-3.8.2 | NOK | http://autobuild.buildroot.net/results/c2d3ee65f4caa9c15940785ea5f6ad545c69163f |     
         arm |                    cmake-3.8.2 | NOK | http://autobuild.buildroot.net/results/c064266e567457fb9427719a697849799d1007c2 |     
   powerpc64 |                    cmake-3.8.2 | NOK | http://autobuild.buildroot.net/results/5c6965036fff7e2b2b066b7a27cac105547d1e2a |     
        i686 |              dbus-python-1.2.4 | NOK | http://autobuild.buildroot.net/results/669471450b7532949d25c181e3db12eea5445405 | ORPH
         arc |              dbus-python-1.2.4 | NOK | http://autobuild.buildroot.net/results/4cf7ff3f58162892062b8a568e3121352d5ea222 | ORPH
      x86_64 |                    evemu-2.7.0 | NOK | http://autobuild.buildroot.net/results/953f9f3e5b2b2268f7711f30f72c22b27b97e6f2 |     
         arm |                    evemu-2.7.0 | NOK | http://autobuild.buildroot.net/results/e2ed46ca0200381f4c044c4f13b7ac70896da5e4 |     
        m68k |                     flex-2.6.4 | NOK | http://autobuild.buildroot.net/results/2e00627b8742dcbdfde94d44eedae28d0b0c9847 | ORPH
        m68k |                     flex-2.6.4 | NOK | http://autobuild.buildroot.net/results/128e7602bb50a80e5c127621b47f82b295c6e2a2 | ORPH
         arm |                     flex-2.6.4 | NOK | http://autobuild.buildroot.net/results/31080fba6ca85c6f5bbc3785e180a51b4ce96d28 | ORPH
         arm |               ghostscript-9.21 | TIM | http://autobuild.buildroot.net/results/35c0841eda7f96ad572c28ae7ab8b09ccddf6705 |     
    mips64el |                 host-mtd-2.0.1 | NOK | http://autobuild.buildroot.net/results/746c5fc47e67e6a1fa1745504a7f992966835972 | ORPH
         arm |                 host-mtd-2.0.1 | NOK | http://autobuild.buildroot.net/results/730c6a7570755455de8013fdcf8a2aee4b3aadbc | ORPH
     aarch64 |                 host-mtd-2.0.1 | NOK | http://autobuild.buildroot.net/results/632367285846a612db5cf59e92da87f05ff99c34 | ORPH
       nios2 | host-squashfs-3de1687d7432e... | NOK | http://autobuild.buildroot.net/results/7157fa83b02f07341a60aabef4e7ef3169b7260b |     
    mips64el | host-squashfs-3de1687d7432e... | NOK | http://autobuild.buildroot.net/results/ecaf395b9179f85422fbd6ad583650a495384983 |     
      xtensa |       host-uboot-tools-2017.07 | NOK | http://autobuild.buildroot.net/results/7ba560352e38bc52dfeb183c3725f59ed219e2ff | ORPH
         arm |       host-uboot-tools-2017.07 | NOK | http://autobuild.buildroot.net/results/5a011478e7a55fa67c6eb2e2062a5dbf2a3315b2 | ORPH
         arc |       host-uboot-tools-2017.07 | NOK | http://autobuild.buildroot.net/results/2abea409951cb2706cadd6ea6ed24b0e0070f921 | ORPH
       nios2 |       host-uboot-tools-2017.07 | NOK | http://autobuild.buildroot.net/results/64cec783c651bdb8b35245d84bdbd1891a2d10b0 | ORPH
     aarch64 |       host-uboot-tools-2017.07 | NOK | http://autobuild.buildroot.net/results/082e4692552790dc6d2f5f0a3b778b491321e28c | ORPH
        i686 |       host-uboot-tools-2017.07 | NOK | http://autobuild.buildroot.net/results/3da4f68a592c7274f174642c5cfd4091122ca20f | ORPH
        i686 |       host-uboot-tools-2017.07 | NOK | http://autobuild.buildroot.net/results/5ded66285270d4f027268b1206a398812dce5c52 | ORPH
    mips64el | host-vboot-utils-bbdd62f9b0... | NOK | http://autobuild.buildroot.net/results/07a39cf8a5d01fe0b7c80bdfbd8a08e101bded55 |     
         arm | host-vboot-utils-bbdd62f9b0... | NOK | http://autobuild.buildroot.net/results/b00231ecb72224a35cb1d3f5659e38857dd0217e |     
     powerpc | host-vboot-utils-bbdd62f9b0... | NOK | http://autobuild.buildroot.net/results/5b4d663d2f22dd51cd3bd78e03c2695da97c7f9b |     
         arm | host-vboot-utils-bbdd62f9b0... | NOK | http://autobuild.buildroot.net/results/c45fbcc9054454471adb1c371ff0233f905e00e6 |     
     powerpc | host-vboot-utils-bbdd62f9b0... | NOK | http://autobuild.buildroot.net/results/9c551dbcab381d2b1ceff345cfcfb40d7a7293f8 |     
     powerpc |                    luvi-v2.7.6 | NOK | http://autobuild.buildroot.net/results/75d11fffbf0237e709617c95d325f02bb7d4036a |     
    mips64el |                  mesa3d-17.2.2 | NOK | http://autobuild.buildroot.net/results/97c1e2ff3170d5a88812eb146750ad0b66e7e95e |     
    mips64el |                  mesa3d-17.2.2 | NOK | http://autobuild.buildroot.net/results/4acb79d4abcd1394769541954af62ce8e8962b4d |     
         arm |                  mesa3d-17.2.2 | NOK | http://autobuild.buildroot.net/results/8bbbd95e880b803ed986ce7dff78a8b3c6ae8b71 |     
 powerpc64le |                  mesa3d-17.2.2 | NOK | http://autobuild.buildroot.net/results/7d8fef3b0dfa5fb04831162003f54d476de21a69 |     
    mips64el |                  mesa3d-17.2.2 | NOK | http://autobuild.buildroot.net/results/19ba2378a8683e7c680d99ebf611c4a67c58b7c3 |     
         arm |          mesa3d-headers-17.2.2 | NOK | http://autobuild.buildroot.net/results/d905e4b70c650e2cd2df8ac2e172d73400c960b0 |     
         arm |                    mp4v2-2.0.0 | NOK | http://autobuild.buildroot.net/results/995623de06c10e210801f6ac8922212b2479896e |     
         arc |                      nmap-7.60 | NOK | http://autobuild.buildroot.net/results/eb2739bf5e3c77fcbe317ca64809fbb4da56fbca |     
         arm |                 openjpeg-2.2.0 | NOK | http://autobuild.buildroot.net/results/59850ee746d9a835f864ba800c01d7bb43c83fec |     
     powerpc |                 openjpeg-2.2.0 | NOK | http://autobuild.buildroot.net/results/72137c87599e4cd49711b24b25d7129f4f212cd1 |     
    mips64el |                 openjpeg-2.2.0 | NOK | http://autobuild.buildroot.net/results/4a4fb5f742b34ab0efbb5ad517c6a0b434bd44c0 |     
      mipsel |                    perl-5.26.1 | NOK | http://autobuild.buildroot.net/results/1a53853f169be20882688fce362a71ce09bf5c81 |     
      xtensa |                    perl-5.26.1 | NOK | http://autobuild.buildroot.net/results/38b187165ea21f194d8a7179ef71f47657446d0b |     
     powerpc |                 pinentry-1.0.0 | NOK | http://autobuild.buildroot.net/results/3b1c0b3d1098449db4834b04e3b25446a925e4a4 |     
     powerpc |                       qt-4.8.7 | NOK | http://autobuild.buildroot.net/results/3b9c8bb9dc4594c9793b0e29c0b75d0d360e27cd | ORPH
         arm |                  qt5base-5.6.2 | NOK | http://autobuild.buildroot.net/results/1efe81938a578a231511ad4ce6a4db4804f21b0a |     
         arm |                     sdl2-2.0.6 | NOK | http://autobuild.buildroot.net/results/c5fb446ec1a16a57a144a837579a61caae08413b |     
        bfin |      toolchain-external-custom | NOK | http://autobuild.buildroot.net/results/4412d0c729b6ef8aa4f0221fe99d9bbc61d5ef48 |     
         sh4 |         wireguard-0.0.20171001 | NOK | http://autobuild.buildroot.net/results/c162020b27fd3642e98c2e18c8782319c46782db | ORPH
       sparc |         wireguard-0.0.20171001 | NOK | http://autobuild.buildroot.net/results/dc41694b952ed9aada4af2f55e8e489f0d651e55 | ORPH
        bfin |         wireguard-0.0.20171001 | NOK | http://autobuild.buildroot.net/results/96c58b90de382b7fa0cf66df21948dc4ccdb76e0 | ORPH
        or1k |         wireguard-0.0.20171001 | NOK | http://autobuild.buildroot.net/results/4023629a3415f3621644fb6f46355ebd67b9507a | ORPH
         arc |         wireguard-0.0.20171001 | NOK | http://autobuild.buildroot.net/results/c4af8d954fce53625fff308a6823123727f8529e | ORPH

-- 
http://autobuild.buildroot.net

^ permalink raw reply

* Re: [PATCH v2 13/17] phy: qcom-qmp: Add support for QMP V3 USB3 PHY
From: Manu Gautam @ 2017-10-05  6:30 UTC (permalink / raw)
  To: Jack Pham
  Cc: Kishon Vijay Abraham I, Felipe Balbi, linux-arm-msm, linux-usb,
	Vivek Gautam, Varadarajan Narayanan, Viresh Kumar, Fengguang Wu,
	Wei Yongjun, open list:GENERIC PHY FRAMEWORK
In-Reply-To: <20170927175906.GB12812@usblab-sd-06.qualcomm.com>



On 9/27/2017 11:29 PM, Jack Pham wrote:
> On Wed, Sep 27, 2017 at 02:29:09PM +0530, Manu Gautam wrote:
>> QMP V3 USB3 PHY is a DP USB combo PHY with
>> dual RX/TX lanes to support type-c. There is a
>> separate block DP_COM for configuration related
>> to type-c or DP. Add support for dp_com region
>> and secondary rx/tx lanes initialization.
> Clarify "DP" as DisplayPort here?

Yes, DP implies DisplayPort. I will update commit text.

> Jack

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* Re: [PATCH 06/11] MIPS: cmpxchg: Implement __cmpxchg() as a function
From: Greg Ungerer @ 2017-10-05  6:29 UTC (permalink / raw)
  To: Paul Burton; +Cc: Ralf Baechle, linux-mips

Hi Paul,

On Fri, 9 Jun 2017 17:26:38 -0700, Paul Burton wrote:
> Replace the macro definition of __cmpxchg() with an inline function,
> which is easier to read & modify. The cmpxchg() & cmpxchg_local() macros
> are adjusted to call the new __cmpxchg() function.
> 
> Signed-off-by: Paul Burton <paul.burton@xxxxxxxxxx>
> Cc: Ralf Baechle <ralf@xxxxxxxxxxxxxx>
> Cc: linux-mips@xxxxxxxxxxxxxx

I think this patch is breaking user space for me. I say "think"
because it is a bit tricky to bisect for the few patches previous
to this one since they won't compile cleanly for me (due to this
https://www.spinics.net/lists/mips/msg68727.html).

I have a Cavium Octeon 5010 MIPS64 CPU on a custom board, have been
running it for years running various kernel versions. Linux-4.13
breaks for me, and I bisected back to this change.

What I see is user space bomb strait after boot with console messages
like this:

mount[37] killed because of sig - 11

STACK DUMP:
CPU: 0 PID: 37 Comm: mount Not tainted 4.13.0-uc0 #8
task: 8000000007d14200 task.stack: 8000000007f18000
$ 0   : 0000000000000000 000000ffffd23f70 000000000000001a 000000000001a7d0
$ 4   : 0000000125af9760 0000000125af9718 0000000125af9748 0000000000000001
$ 8   : 2f2f2f2f2f2f2f2f 8101010101010100 0000000000000000 00000000ffffffff
$12   : 000000fff79f6000 000000fff7980f00 000000fff79887d8 0000000000000018
$16   : 0000000125af9718 0000000125af9760 0000000125af9748 0000000120054cd8
$20   : 000000012006f3a0 00000001200083ac 0000000120059fa0 000000012006f3a0
$24   : 00000000000001c8 000000fff798f7d0                                  
$28   : 000000fff79f75e0 000000ffffd23fe0 0000000120010000 0000000120015820
Hi    : 00000000000001b6
Lo    : 000000000001b0b9
epc   : 000000fff798f7f4 0x000000fff798f7f4
ra    : 0000000120015820 0x0000000120015820
Status: 00008cf3	KX SX UX USER EXL IE 
Cause : 00800020 (ExcCode 08)
PrId  : 000d0601 (Cavium Octeon+)
000000ffffc9b000-000000ffffcbc000 rwxp 000000fffffdf000 00:00 0 

I get a lot of them from various programs running from rc scripts.
It never manages to fully boot to login/shell.

If I take the linux-4.12 arch/mips/include/asm/cmpxchg.h and drop that
in place on a linux-4.13 (or even linux-4.14-rc3) I can compile and
run everything successfully.

Any thoughts?

Regards
Greg



> ---
> 
>  arch/mips/include/asm/cmpxchg.h | 59 ++++++++++++++++++++++-------------------
>  1 file changed, 32 insertions(+), 27 deletions(-)
> 
> diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h
> index e9c1e97bc29d..516cb66f066b 100644
> --- a/arch/mips/include/asm/cmpxchg.h
> +++ b/arch/mips/include/asm/cmpxchg.h
> @@ -34,7 +34,7 @@
>   *
>   * - Get an error at link-time due to the call to the missing function.
>   */
> -extern void __cmpxchg_called_with_bad_pointer(void)
> +extern unsigned long __cmpxchg_called_with_bad_pointer(void)
>  	__compiletime_error("Bad argument size for cmpxchg");
>  extern unsigned long __xchg_called_with_bad_pointer(void)
>  	__compiletime_error("Bad argument size for xchg");
> @@ -137,38 +137,43 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
>  	__ret;								\
>  })
>  
> -#define __cmpxchg(ptr, old, new, pre_barrier, post_barrier)		\
> +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
> +				      unsigned long new, unsigned int size)
> +{
> +	switch (size) {
> +	case 4:
> +		return __cmpxchg_asm("ll", "sc", (volatile u32 *)ptr, old, new);
> +
> +	case 8:
> +		/* lld/scd are only available for MIPS64 */
> +		if (!IS_ENABLED(CONFIG_64BIT))
> +			return __cmpxchg_called_with_bad_pointer();
> +
> +		return __cmpxchg_asm("lld", "scd", (volatile u64 *)ptr, old, new);
> +
> +	default:
> +		return __cmpxchg_called_with_bad_pointer();
> +	}
> +}
> +
> +#define cmpxchg_local(ptr, old, new)					\
> +	((__typeof__(*(ptr)))						\
> +		__cmpxchg((ptr),					\
> +			  (unsigned long)(__typeof__(*(ptr)))(old),	\
> +			  (unsigned long)(__typeof__(*(ptr)))(new),	\
> +			  sizeof(*(ptr))))
> +
> +#define cmpxchg(ptr, old, new)						\
>  ({									\
> -	__typeof__(ptr) __ptr = (ptr);					\
> -	__typeof__(*(ptr)) __old = (old);				\
> -	__typeof__(*(ptr)) __new = (new);				\
> -	__typeof__(*(ptr)) __res = 0;					\
> -									\
> -	pre_barrier;							\
> -									\
> -	switch (sizeof(*(__ptr))) {					\
> -	case 4:								\
> -		__res = __cmpxchg_asm("ll", "sc", __ptr, __old, __new); \
> -		break;							\
> -	case 8:								\
> -		if (sizeof(long) == 8) {				\
> -			__res = __cmpxchg_asm("lld", "scd", __ptr,	\
> -					   __old, __new);		\
> -			break;						\
> -		}							\
> -	default:							\
> -		__cmpxchg_called_with_bad_pointer();			\
> -		break;							\
> -	}								\
> +	__typeof__(*(ptr)) __res;					\
>  									\
> -	post_barrier;							\
> +	smp_mb__before_llsc();						\
> +	__res = cmpxchg_local((ptr), (old), (new));			\
> +	smp_llsc_mb();							\
>  									\
>  	__res;								\
>  })
>  
> -#define cmpxchg(ptr, old, new)		__cmpxchg(ptr, old, new, smp_mb__before_llsc(), smp_llsc_mb())
> -#define cmpxchg_local(ptr, old, new)	__cmpxchg(ptr, old, new, , )
> -
>  #ifdef CONFIG_64BIT
>  #define cmpxchg64_local(ptr, o, n)					\
>    ({									\
> -- 
> 2.13.1

^ permalink raw reply

* Re: [PATCH v8 2/2] media:imx274 V4l2 driver for Sony imx274 CMOS sensor
From: Sakari Ailus @ 2017-10-05  6:29 UTC (permalink / raw)
  To: Leon Luo
  Cc: mchehab, robh+dt, mark.rutland, hans.verkuil, sakari.ailus,
	linux-media, devicetree, linux-kernel, soren.brinkmann
In-Reply-To: <20171005000621.27841-2-leonl@leopardimaging.com>

On Wed, Oct 04, 2017 at 05:06:21PM -0700, Leon Luo wrote:
> The imx274 is a Sony CMOS image sensor that has 1/2.5 image size.
> It supports up to 3840x2160 (4K) 60fps, 1080p 120fps. The interface
> is 4-lane MIPI CSI-2 running at 1.44Gbps each.
> 
> This driver has been tested on Xilinx ZCU102 platform with a Leopard
> LI-IMX274MIPI-FMC camera board.
> 
> Support for the following features:
> -Resolutions: 3840x2160, 1920x1080, 1280x720
> -Frame rate: 3840x2160 : 5 – 60fps
>             1920x1080 : 5 – 120fps
>             1280x720 : 5 – 120fps
> -Exposure time: 16 – (frame interval) micro-seconds
> -Gain: 1x - 180x
> -VFLIP: enable/disabledrivers/media/i2c/imx274.c
> -Test pattern: 12 test patterns
> 
> Signed-off-by: Leon Luo <leonl@leopardimaging.com>
> Tested-by: Sören Brinkmann <soren.brinkmann@xilinx.com>
> Acked-by: Sakari Ailus <sakari.ailus@iki.fi>

Thanks!

Applied with MEDIA_CAMERA_SUPPORT dependency to Kconfig.

-- 
Sakari Ailus
e-mail: sakari.ailus@iki.fi

^ permalink raw reply

* Re: [PATCH v8 2/2] media:imx274 V4l2 driver for Sony imx274 CMOS sensor
From: Sakari Ailus @ 2017-10-05  6:29 UTC (permalink / raw)
  To: Leon Luo
  Cc: mchehab-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, hans.verkuil-FYB4Gu1CFyUAvxtiuMwx3w,
	sakari.ailus-VuQAYsv1563Yd54FQh9/CA,
	linux-media-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	soren.brinkmann-gjFFaj9aHVfQT0dZR+AlfA
In-Reply-To: <20171005000621.27841-2-leonl-+iDsysdzPxZTt5vwKEO50dBPR1lH4CV8@public.gmane.org>

On Wed, Oct 04, 2017 at 05:06:21PM -0700, Leon Luo wrote:
> The imx274 is a Sony CMOS image sensor that has 1/2.5 image size.
> It supports up to 3840x2160 (4K) 60fps, 1080p 120fps. The interface
> is 4-lane MIPI CSI-2 running at 1.44Gbps each.
> 
> This driver has been tested on Xilinx ZCU102 platform with a Leopard
> LI-IMX274MIPI-FMC camera board.
> 
> Support for the following features:
> -Resolutions: 3840x2160, 1920x1080, 1280x720
> -Frame rate: 3840x2160 : 5 – 60fps
>             1920x1080 : 5 – 120fps
>             1280x720 : 5 – 120fps
> -Exposure time: 16 – (frame interval) micro-seconds
> -Gain: 1x - 180x
> -VFLIP: enable/disabledrivers/media/i2c/imx274.c
> -Test pattern: 12 test patterns
> 
> Signed-off-by: Leon Luo <leonl-+iDsysdzPxZTt5vwKEO50dBPR1lH4CV8@public.gmane.org>
> Tested-by: Sören Brinkmann <soren.brinkmann-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
> Acked-by: Sakari Ailus <sakari.ailus-X3B1VOXEql0@public.gmane.org>

Thanks!

Applied with MEDIA_CAMERA_SUPPORT dependency to Kconfig.

-- 
Sakari Ailus
e-mail: sakari.ailus-X3B1VOXEql0@public.gmane.org
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 2/2] kprobes: propagate error from disarm_kprobe_ftrace()
From: Masami Hiramatsu @ 2017-10-05  6:28 UTC (permalink / raw)
  To: Jessica Yu
  Cc: Petr Mladek, Ananth N Mavinakayanahalli, Anil S Keshavamurthy,
	David S . Miller, Ingo Molnar, Josh Poimboeuf, Joe Lawrence,
	Jiri Kosina, Miroslav Benes, Steven Rostedt, live-patching,
	linux-kernel
In-Reply-To: <20171004191414.8872-3-jeyu@kernel.org>

On Wed,  4 Oct 2017 21:14:14 +0200
Jessica Yu <jeyu@kernel.org> wrote:

> Improve error handling when disarming ftrace-based kprobes. Like with
> arm_kprobe_ftrace(), propagate any errors from disarm_kprobe_ftrace() so
> that we do not disable/unregister kprobes that are still armed. In other
> words, unregister_kprobe() and disable_kprobe() should not report success
> if the kprobe could not be disarmed.
> 
> disarm_all_kprobes() keeps its current behavior and attempts to
> disarm all kprobes. It returns the last encountered error and gives a
> warning if not all kprobes could be disarmed.
> 
> This patch is based on Petr Mladek's original patchset (patches 2 and 3)
> back in 2015, which improved kprobes error handling, found here:
> 
>    https://lkml.org/lkml/2015/2/26/452
> 
> However, further work on this had been paused since then and the patches
> were not upstreamed.
> 

OK, this looks good to me :)

Acked-by: Masami Hiramatsu <mhiramat@kernel.org>

Thanks!

> Based-on-patches-by: Petr Mladek <pmladek@suse.com>
> Signed-off-by: Jessica Yu <jeyu@kernel.org>
> ---
>  kernel/kprobes.c | 76 +++++++++++++++++++++++++++++++++++++-------------------
>  1 file changed, 51 insertions(+), 25 deletions(-)
> 
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index 6e889be0d93c..2e9edf646ae3 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -1003,23 +1003,27 @@ static int arm_kprobe_ftrace(struct kprobe *p)
>  }
>  
>  /* Caller must lock kprobe_mutex */
> -static void disarm_kprobe_ftrace(struct kprobe *p)
> +static int disarm_kprobe_ftrace(struct kprobe *p)
>  {
> -	int ret;
> +	int ret = 0;
>  
> -	kprobe_ftrace_enabled--;
> -	if (kprobe_ftrace_enabled == 0) {
> +	if (kprobe_ftrace_enabled == 1) {
>  		ret = unregister_ftrace_function(&kprobe_ftrace_ops);
> -		WARN(ret < 0, "Failed to init kprobe-ftrace (%d)\n", ret);
> +		if (WARN(ret < 0, "Failed to unregister kprobe-ftrace (%d)\n", ret))
> +			return ret;
>  	}
> +
> +	kprobe_ftrace_enabled--;
> +
>  	ret = ftrace_set_filter_ip(&kprobe_ftrace_ops,
>  			   (unsigned long)p->addr, 1, 0);
>  	WARN(ret < 0, "Failed to disarm kprobe-ftrace at %p (%d)\n", p->addr, ret);
> +	return ret;
>  }
>  #else	/* !CONFIG_KPROBES_ON_FTRACE */
>  #define prepare_kprobe(p)	arch_prepare_kprobe(p)
>  #define arm_kprobe_ftrace(p)	(0)
> -#define disarm_kprobe_ftrace(p)	do {} while (0)
> +#define disarm_kprobe_ftrace(p)	(0)
>  #endif
>  
>  /* Arm a kprobe with text_mutex */
> @@ -1038,18 +1042,18 @@ static int arm_kprobe(struct kprobe *kp)
>  }
>  
>  /* Disarm a kprobe with text_mutex */
> -static void disarm_kprobe(struct kprobe *kp, bool reopt)
> +static int disarm_kprobe(struct kprobe *kp, bool reopt)
>  {
> -	if (unlikely(kprobe_ftrace(kp))) {
> -		disarm_kprobe_ftrace(kp);
> -		return;
> -	}
> +	if (unlikely(kprobe_ftrace(kp)))
> +		return disarm_kprobe_ftrace(kp);
>  
>  	cpus_read_lock();
>  	mutex_lock(&text_mutex);
>  	__disarm_kprobe(kp, reopt);
>  	mutex_unlock(&text_mutex);
>  	cpus_read_unlock();
> +
> +	return 0;
>  }
>  
>  /*
> @@ -1627,11 +1631,12 @@ static int aggr_kprobe_disabled(struct kprobe *ap)
>  static struct kprobe *__disable_kprobe(struct kprobe *p)
>  {
>  	struct kprobe *orig_p;
> +	int ret;
>  
>  	/* Get an original kprobe for return */
>  	orig_p = __get_valid_kprobe(p);
>  	if (unlikely(orig_p == NULL))
> -		return NULL;
> +		return ERR_PTR(-EINVAL);
>  
>  	if (!kprobe_disabled(p)) {
>  		/* Disable probe if it is a child probe */
> @@ -1645,8 +1650,13 @@ static struct kprobe *__disable_kprobe(struct kprobe *p)
>  			 * should have already been disarmed, so
>  			 * skip unneed disarming process.
>  			 */
> -			if (!kprobes_all_disarmed)
> -				disarm_kprobe(orig_p, true);
> +			if (!kprobes_all_disarmed) {
> +				ret = disarm_kprobe(orig_p, true);
> +				if (ret) {
> +					p->flags &= ~KPROBE_FLAG_DISABLED;
> +					return ERR_PTR(ret);
> +				}
> +			}
>  			orig_p->flags |= KPROBE_FLAG_DISABLED;
>  		}
>  	}
> @@ -1663,8 +1673,8 @@ static int __unregister_kprobe_top(struct kprobe *p)
>  
>  	/* Disable kprobe. This will disarm it if needed. */
>  	ap = __disable_kprobe(p);
> -	if (ap == NULL)
> -		return -EINVAL;
> +	if (IS_ERR(ap))
> +		return PTR_ERR(ap);
>  
>  	if (ap == p)
>  		/*
> @@ -2095,12 +2105,14 @@ static void kill_kprobe(struct kprobe *p)
>  int disable_kprobe(struct kprobe *kp)
>  {
>  	int ret = 0;
> +	struct kprobe *p;
>  
>  	mutex_lock(&kprobe_mutex);
>  
>  	/* Disable this kprobe */
> -	if (__disable_kprobe(kp) == NULL)
> -		ret = -EINVAL;
> +	p = __disable_kprobe(kp);
> +	if (IS_ERR(p))
> +		ret = PTR_ERR(p);
>  
>  	mutex_unlock(&kprobe_mutex);
>  	return ret;
> @@ -2470,34 +2482,48 @@ static int arm_all_kprobes(void)
>  	return ret;
>  }
>  
> -static void disarm_all_kprobes(void)
> +static int disarm_all_kprobes(void)
>  {
>  	struct hlist_head *head;
>  	struct kprobe *p;
> -	unsigned int i;
> +	unsigned int i, errors = 0;
> +	int err, ret = 0;
>  
>  	mutex_lock(&kprobe_mutex);
>  
>  	/* If kprobes are already disarmed, just return */
>  	if (kprobes_all_disarmed) {
>  		mutex_unlock(&kprobe_mutex);
> -		return;
> +		return 0;
>  	}
>  
>  	kprobes_all_disarmed = true;
> -	printk(KERN_INFO "Kprobes globally disabled\n");
>  
>  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
>  		head = &kprobe_table[i];
> +		/* Disarm all kprobes on a best-effort basis */
>  		hlist_for_each_entry_rcu(p, head, hlist) {
> -			if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p))
> -				disarm_kprobe(p, false);
> +			if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p)) {
> +				err = disarm_kprobe(p, false);
> +				if (err) {
> +					errors++;
> +					ret = err;
> +				}
> +			}
>  		}
>  	}
> +
> +	if (errors)
> +		pr_warn("Kprobes globally disabled, but failed to disarm %d kprobes\n", errors);
> +	else
> +		pr_info("Kprobes globally disabled\n");
> +
>  	mutex_unlock(&kprobe_mutex);
>  
>  	/* Wait for disarming all kprobes by optimizer */
>  	wait_for_kprobe_optimizer();
> +
> +	return ret;
>  }
>  
>  /*
> @@ -2540,7 +2566,7 @@ static ssize_t write_enabled_file_bool(struct file *file,
>  	case 'n':
>  	case 'N':
>  	case '0':
> -		disarm_all_kprobes();
> +		ret = disarm_all_kprobes();
>  		break;
>  	default:
>  		return -EINVAL;
> -- 
> 2.13.6
> 


-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply

* Re: [PATCH 1/2] kprobes: propagate error from arm_kprobe_ftrace()
From: Masami Hiramatsu @ 2017-10-05  6:23 UTC (permalink / raw)
  To: Jessica Yu
  Cc: Petr Mladek, Ananth N Mavinakayanahalli, Anil S Keshavamurthy,
	David S . Miller, Ingo Molnar, Josh Poimboeuf, Joe Lawrence,
	Jiri Kosina, Miroslav Benes, Steven Rostedt, live-patching,
	linux-kernel
In-Reply-To: <20171004191414.8872-2-jeyu@kernel.org>

Hi Jessica,

On Wed,  4 Oct 2017 21:14:13 +0200
Jessica Yu <jeyu@kernel.org> wrote:

> Improve error handling when arming ftrace-based kprobes. Specifically, if
> we fail to arm a ftrace-based kprobe, register_kprobe()/enable_kprobe()
> should report an error instead of success. Previously, this has lead to
> confusing situations where register_kprobe() would return 0 indicating
> success, but the kprobe would not be functional if ftrace registration
> during the kprobe arming process had failed. We should therefore take any
> errors returned by ftrace into account and propagate this error so that we
> do not register/enable kprobes that cannot be armed. This can happen if,
> for example, register_ftrace_function() finds an IPMODIFY conflict (since
> kprobe_ftrace_ops has this flag set) and returns an error. Such a conflict
> is possible since livepatches also set the IPMODIFY flag for their ftrace_ops.
> 
> arm_all_kprobes() keeps its current behavior and attempts to arm all
> kprobes. It returns the last encountered error and gives a warning if
> not all kprobes could be armed.
> 
> This patch is based on Petr Mladek's original patchset (patches 2 and 3)
> back in 2015, which improved kprobes error handling, found here:
> 
>    https://lkml.org/lkml/2015/2/26/452
> 
> However, further work on this had been paused since then and the patches
> were not upstreamed.

Ok, I have some comment. See below.

> 
> Based-on-patches-by: Petr Mladek <pmladek@suse.com>
> Signed-off-by: Jessica Yu <jeyu@kernel.org>
> ---
>  kernel/kprobes.c | 87 +++++++++++++++++++++++++++++++++++++++-----------------
>  1 file changed, 61 insertions(+), 26 deletions(-)
> 
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index 2d28377a0e32..6e889be0d93c 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -979,18 +979,27 @@ static int prepare_kprobe(struct kprobe *p)
>  }
>  
>  /* Caller must lock kprobe_mutex */
> -static void arm_kprobe_ftrace(struct kprobe *p)
> +static int arm_kprobe_ftrace(struct kprobe *p)
>  {
> -	int ret;
> +	int ret = 0;
>  
>  	ret = ftrace_set_filter_ip(&kprobe_ftrace_ops,
>  				   (unsigned long)p->addr, 0, 0);
> -	WARN(ret < 0, "Failed to arm kprobe-ftrace at %p (%d)\n", p->addr, ret);
> -	kprobe_ftrace_enabled++;
> -	if (kprobe_ftrace_enabled == 1) {
> +	if (WARN(ret < 0, "Failed to arm kprobe-ftrace at %p (%d)\n", p->addr, ret))
> +		return ret;
> +
> +	if (kprobe_ftrace_enabled == 0) {
>  		ret = register_ftrace_function(&kprobe_ftrace_ops);
> -		WARN(ret < 0, "Failed to init kprobe-ftrace (%d)\n", ret);
> +		if (WARN(ret < 0, "Failed to init kprobe-ftrace (%d)\n", ret))
> +			goto err_ftrace;
>  	}
> +
> +	kprobe_ftrace_enabled++;
> +	return ret;
> +
> +err_ftrace:
> +	ftrace_set_filter_ip(&kprobe_ftrace_ops, (unsigned long)p->addr, 1, 0);
> +	return ret;
>  }
>  
>  /* Caller must lock kprobe_mutex */
> @@ -1009,22 +1018,23 @@ static void disarm_kprobe_ftrace(struct kprobe *p)
>  }
>  #else	/* !CONFIG_KPROBES_ON_FTRACE */
>  #define prepare_kprobe(p)	arch_prepare_kprobe(p)
> -#define arm_kprobe_ftrace(p)	do {} while (0)
> +#define arm_kprobe_ftrace(p)	(0)
>  #define disarm_kprobe_ftrace(p)	do {} while (0)
>  #endif
>  
>  /* Arm a kprobe with text_mutex */
> -static void arm_kprobe(struct kprobe *kp)
> +static int arm_kprobe(struct kprobe *kp)
>  {
> -	if (unlikely(kprobe_ftrace(kp))) {
> -		arm_kprobe_ftrace(kp);
> -		return;
> -	}
> +	if (unlikely(kprobe_ftrace(kp)))
> +		return arm_kprobe_ftrace(kp);
> +
>  	cpus_read_lock();
>  	mutex_lock(&text_mutex);
>  	__arm_kprobe(kp);
>  	mutex_unlock(&text_mutex);
>  	cpus_read_unlock();
> +
> +	return 0;
>  }
>  
>  /* Disarm a kprobe with text_mutex */
> @@ -1363,9 +1373,14 @@ static int register_aggr_kprobe(struct kprobe *orig_p, struct kprobe *p)
>  
>  	if (ret == 0 && kprobe_disabled(ap) && !kprobe_disabled(p)) {
>  		ap->flags &= ~KPROBE_FLAG_DISABLED;
> -		if (!kprobes_all_disarmed)
> +		if (!kprobes_all_disarmed) {
>  			/* Arm the breakpoint again. */
> -			arm_kprobe(ap);
> +			ret = arm_kprobe(ap);
> +			if (ret) {
> +				ap->flags |= KPROBE_FLAG_DISABLED;
> +				list_del_rcu(&p->list);

Nice catch :) this list_del_rcu() is important to keep error case
behavior sane.

> +			}
> +		}
>  	}
>  	return ret;
>  }
> @@ -1570,13 +1585,16 @@ int register_kprobe(struct kprobe *p)
>  	if (ret)
>  		goto out;
>  
> +	if (!kprobes_all_disarmed && !kprobe_disabled(p)) {
> +		ret = arm_kprobe(p);
> +		if (ret)
> +			goto out;
> +	}
> +

No, this is no good. It is a small chance to hit kprobe on other
CPUs before adding it to kprobe_table hashlist. In that case,
we will see a stray breakpoint instruction.

>  	INIT_HLIST_NODE(&p->hlist);
>  	hlist_add_head_rcu(&p->hlist,
>  		       &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
>  
> -	if (!kprobes_all_disarmed && !kprobe_disabled(p))
> -		arm_kprobe(p);
> -

So, you'll have to rollback by hlist_del_rcu() here.
Hmm, by the way, in this case, you also have to add a synchronize_rcu()
in the end of error path, so that user can release kprobe right after
error return of register_kprobe... (I think that's OK because it is not
a hot path)

Thank you,


-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply

* Re: [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
From: Keith Packard @ 2017-10-05  6:23 UTC (permalink / raw)
  To: Dave Airlie; +Cc: LKML, Dave Airlie, Daniel Vetter, dri-devel
In-Reply-To: <CAPM=9ty1ofbZsripB7YO05vhf8qUpad_kdvaD+O6UCvFre=XXg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1125 bytes --]

Dave Airlie <airlied@gmail.com> writes:

> I think a comment in here is definitely warranted with what you expect
> from the idr interface here.

I've added a longer comment where this value is used; I tried replacing
the IDR with a sorted array and the result wasn't any easier to use or
understand. I'm pretty sure it would be more efficient, but as leases
contain only a few objects in the cases we're considering, it's hard to
get worked up about performance when the code is larger and mostly not
any easier to understand. Feel free to take a look at that:

        git://people.freedesktop.org/~keithp/linux drm-lease-array

> Because otherwise you could just memdup_user the array of ids, and
> pass that in without the idr stuff.

Yeah, that part was more efficient. The rest of the places using this
data were longer. I guess I could bail on sorting the array, but I fear
someone would come up with a place needing a huge lease list, and then
we'd find performance issues.

Thanks for your review; I've sent out a new series and pushed it to my
repo in the drm-lease-v4 branch

-- 
-keith

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply

* Re: [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
From: Keith Packard @ 2017-10-05  6:23 UTC (permalink / raw)
  To: Dave Airlie; +Cc: Dave Airlie, dri-devel, LKML
In-Reply-To: <CAPM=9ty1ofbZsripB7YO05vhf8qUpad_kdvaD+O6UCvFre=XXg@mail.gmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 1125 bytes --]

Dave Airlie <airlied@gmail.com> writes:

> I think a comment in here is definitely warranted with what you expect
> from the idr interface here.

I've added a longer comment where this value is used; I tried replacing
the IDR with a sorted array and the result wasn't any easier to use or
understand. I'm pretty sure it would be more efficient, but as leases
contain only a few objects in the cases we're considering, it's hard to
get worked up about performance when the code is larger and mostly not
any easier to understand. Feel free to take a look at that:

        git://people.freedesktop.org/~keithp/linux drm-lease-array

> Because otherwise you could just memdup_user the array of ids, and
> pass that in without the idr stuff.

Yeah, that part was more efficient. The rest of the places using this
data were longer. I guess I could bail on sorting the array, but I fear
someone would come up with a place needing a huge lease list, and then
we'd find performance issues.

Thanks for your review; I've sent out a new series and pushed it to my
repo in the drm-lease-v4 branch

-- 
-keith

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* [PATCH v2 3/5] clk: aspeed: Add platform driver and register PLLs
From: Joel Stanley @ 2017-10-05  6:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171004211820.GX457@codeaurora.org>

On Thu, Oct 5, 2017 at 6:48 AM, Stephen Boyd <sboyd@codeaurora.org> wrote:
> On 10/03, Joel Stanley wrote:
>> On Tue, Oct 3, 2017 at 6:54 AM, Stephen Boyd <sboyd@codeaurora.org> wrote:
>> > On 09/21, Joel Stanley wrote:
>> >> @@ -160,6 +191,104 @@ static struct clk_hw *aspeed_calc_pll(const char *name, u32 val)
>> >> +     /*
>> >> +      * Memory controller (M-PLL) PLL. This clock is configured by the
>> >> +      * bootloader, and is exposed to Linux as a read-only clock rate.
>> >> +      */
>> >> +     regmap_read(map, ASPEED_MPLL_PARAM, &val);
>> >> +     aspeed_clk_data->hws[ASPEED_CLK_MPLL] = aspeed_calc_pll("mpll", val);
>> >> +
>> >> +     /* SD/SDIO clock divider (TODO: There's a gate too) */
>> >> +     hw = clk_hw_register_divider_table(NULL, "sdio", "hpll", 0,
>> >
>> > Please pass your dev pointer here from the platform device.
>> >
>> >> +                     scu_base + ASPEED_CLK_SELECTION, 12, 3, 0,
>> >> +                     div_table,
>> >> +                     &aspeed_clk_lock);
>> >
>> > And check for errors? Perhaps use devm_clk_hw_regsiter() APIs and
>> > construct the dividers and muxes directly instead of using the
>> > basic type registration APIs.
>>
>> Do you think that devm_ is overkill, given we will never unload this driver?
>
> Is probe defer going to happen? Even if unload can't happen,
> probe defer is a concern unless that is also ruled out.

As I understand it, I will only get an EPROBE_DEFER if I'm requesting
something from another driver?

If that's the case then we can rule that out.

>>
>> Can you explain why you suggest to construct the structures directly
>> instead of using the APIs?
>
> There aren't devm APIs for some of these basic clk type
> registration functions.
>
>>
>> I had a read of the basic type registration functions, and the
>> relevant failure paths are memory allocation failures. If we're out of
>> memory that early in boot then things have gone pretty bad.
>>
>> I can add checks for null and bail out; I don't think there's value in
>> freeing the allocated memory: if a system can't load it's clock driver
>> then it's super hosed.
>
> If we can't proceed without this driver because it's super hosed,
> then perhaps we need to panic the system on errors here. Should
> be simple enough to add some error checks and goto panic("Things
> are super hosed").

Okay. I added checks in v4. Does that look ok you you?

Cheers,

Joel

^ permalink raw reply

* Re: [PATCH v2 3/5] clk: aspeed: Add platform driver and register PLLs
From: Joel Stanley @ 2017-10-05  6:22 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Lee Jones, Michael Turquette, Linux Kernel Mailing List,
	linux-clk, Linux ARM, Andrew Jeffery, Benjamin Herrenschmidt,
	Jeremy Kerr, Rick Altherr, Ryan Chen, Arnd Bergmann
In-Reply-To: <20171004211820.GX457@codeaurora.org>

On Thu, Oct 5, 2017 at 6:48 AM, Stephen Boyd <sboyd@codeaurora.org> wrote:
> On 10/03, Joel Stanley wrote:
>> On Tue, Oct 3, 2017 at 6:54 AM, Stephen Boyd <sboyd@codeaurora.org> wrote:
>> > On 09/21, Joel Stanley wrote:
>> >> @@ -160,6 +191,104 @@ static struct clk_hw *aspeed_calc_pll(const char *name, u32 val)
>> >> +     /*
>> >> +      * Memory controller (M-PLL) PLL. This clock is configured by the
>> >> +      * bootloader, and is exposed to Linux as a read-only clock rate.
>> >> +      */
>> >> +     regmap_read(map, ASPEED_MPLL_PARAM, &val);
>> >> +     aspeed_clk_data->hws[ASPEED_CLK_MPLL] = aspeed_calc_pll("mpll", val);
>> >> +
>> >> +     /* SD/SDIO clock divider (TODO: There's a gate too) */
>> >> +     hw = clk_hw_register_divider_table(NULL, "sdio", "hpll", 0,
>> >
>> > Please pass your dev pointer here from the platform device.
>> >
>> >> +                     scu_base + ASPEED_CLK_SELECTION, 12, 3, 0,
>> >> +                     div_table,
>> >> +                     &aspeed_clk_lock);
>> >
>> > And check for errors? Perhaps use devm_clk_hw_regsiter() APIs and
>> > construct the dividers and muxes directly instead of using the
>> > basic type registration APIs.
>>
>> Do you think that devm_ is overkill, given we will never unload this driver?
>
> Is probe defer going to happen? Even if unload can't happen,
> probe defer is a concern unless that is also ruled out.

As I understand it, I will only get an EPROBE_DEFER if I'm requesting
something from another driver?

If that's the case then we can rule that out.

>>
>> Can you explain why you suggest to construct the structures directly
>> instead of using the APIs?
>
> There aren't devm APIs for some of these basic clk type
> registration functions.
>
>>
>> I had a read of the basic type registration functions, and the
>> relevant failure paths are memory allocation failures. If we're out of
>> memory that early in boot then things have gone pretty bad.
>>
>> I can add checks for null and bail out; I don't think there's value in
>> freeing the allocated memory: if a system can't load it's clock driver
>> then it's super hosed.
>
> If we can't proceed without this driver because it's super hosed,
> then perhaps we need to panic the system on errors here. Should
> be simple enough to add some error checks and goto panic("Things
> are super hosed").

Okay. I added checks in v4. Does that look ok you you?

Cheers,

Joel

^ permalink raw reply

* Re: [PATCH] ALSA: sh: aica: Convert timers to use timer_setup()
From: Takashi Iwai @ 2017-10-05  6:22 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-kernel, alsa-devel, Bhumika Goyal, Mark Brown,
	Thomas Gleixner, Jaroslav Kysela
In-Reply-To: <20171005005336.GA23796@beast>

On Thu, 05 Oct 2017 02:53:36 +0200,
Kees Cook wrote:
> 
> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly. This requires adding a pointer to
> hold the timer's target substream, as there won't be a way to pass this in
> the future.
> 
> Cc: Jaroslav Kysela <perex@perex.cz>
> Cc: Takashi Iwai <tiwai@suse.com>
> Cc: Bhumika Goyal <bhumirks@gmail.com>
> Cc: Mark Brown <broonie@kernel.org>
> Cc: alsa-devel@alsa-project.org
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
> This requires commit 686fef928bba ("timer: Prepare to change timer
> callback argument type") in v4.14-rc3, but should be otherwise
> stand-alone.

The conversions look straightforward, so I'm going to apply it (and
other two you posted).  But now I wonder why only three were chosen.
Will you keep working on the rest usages in sound/*, or would you
expect us doing the rest?


thanks,

Takashi

^ permalink raw reply

* Re: [PATCH] ALSA: sh: aica: Convert timers to use timer_setup()
From: Takashi Iwai @ 2017-10-05  6:22 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-kernel, alsa-devel, Bhumika Goyal, Mark Brown,
	Thomas Gleixner, Jaroslav Kysela
In-Reply-To: <20171005005336.GA23796@beast>

On Thu, 05 Oct 2017 02:53:36 +0200,
Kees Cook wrote:
> 
> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly. This requires adding a pointer to
> hold the timer's target substream, as there won't be a way to pass this in
> the future.
> 
> Cc: Jaroslav Kysela <perex@perex.cz>
> Cc: Takashi Iwai <tiwai@suse.com>
> Cc: Bhumika Goyal <bhumirks@gmail.com>
> Cc: Mark Brown <broonie@kernel.org>
> Cc: alsa-devel@alsa-project.org
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
> This requires commit 686fef928bba ("timer: Prepare to change timer
> callback argument type") in v4.14-rc3, but should be otherwise
> stand-alone.

The conversions look straightforward, so I'm going to apply it (and
other two you posted).  But now I wonder why only three were chosen.
Will you keep working on the rest usages in sound/*, or would you
expect us doing the rest?


thanks,

Takashi

^ permalink raw reply

* [PATCH 1/6] drm: Pass struct drm_file * to  __drm_mode_object_find
From: Keith Packard @ 2017-10-05  6:13 UTC (permalink / raw)
  To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
In-Reply-To: <20171005061310.29919-1-keithp@keithp.com>

This will allow __drm_mode_object_file to be extended to perform
access control checks based on the file in use.

Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Keith Packard <keithp@keithp.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c   | 16 ++++++++--------
 drivers/gpu/drm/amd/amdgpu/dce_virtual.c         |  4 ++--
 drivers/gpu/drm/ast/ast_mode.c                   |  2 +-
 drivers/gpu/drm/bochs/bochs_kms.c                |  2 +-
 drivers/gpu/drm/cirrus/cirrus_mode.c             |  2 +-
 drivers/gpu/drm/drm_atomic.c                     |  8 ++++----
 drivers/gpu/drm/drm_atomic_helper.c              |  2 +-
 drivers/gpu/drm/drm_color_mgmt.c                 |  4 ++--
 drivers/gpu/drm/drm_connector.c                  |  2 +-
 drivers/gpu/drm/drm_crtc.c                       |  8 ++++----
 drivers/gpu/drm/drm_crtc_internal.h              |  1 +
 drivers/gpu/drm/drm_encoder.c                    |  2 +-
 drivers/gpu/drm/drm_framebuffer.c                |  9 +++++----
 drivers/gpu/drm/drm_mode_object.c                | 10 ++++++----
 drivers/gpu/drm/drm_plane.c                      | 14 +++++++-------
 drivers/gpu/drm/drm_probe_helper.c               |  2 +-
 drivers/gpu/drm/drm_property.c                   |  6 +++---
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c |  2 +-
 drivers/gpu/drm/i915/intel_display.c             |  2 +-
 drivers/gpu/drm/i915/intel_overlay.c             |  2 +-
 drivers/gpu/drm/i915/intel_sprite.c              |  2 +-
 drivers/gpu/drm/mgag200/mgag200_mode.c           |  2 +-
 drivers/gpu/drm/nouveau/nouveau_connector.c      |  4 ++--
 drivers/gpu/drm/radeon/r100.c                    |  2 +-
 drivers/gpu/drm/radeon/r600_cs.c                 |  2 +-
 drivers/gpu/drm/radeon/radeon_connectors.c       | 16 ++++++++--------
 drivers/gpu/drm/udl/udl_connector.c              |  2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c            |  4 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c              |  2 +-
 include/drm/drm_connector.h                      |  3 ++-
 include/drm/drm_crtc.h                           |  5 +++--
 include/drm/drm_encoder.h                        |  3 ++-
 include/drm/drm_framebuffer.h                    |  1 +
 include/drm/drm_mode_object.h                    |  2 ++
 include/drm/drm_plane.h                          |  3 ++-
 include/drm/drm_property.h                       |  3 ++-
 36 files changed, 84 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index 8d1cf2d3e663..a6c17353e57d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
@@ -231,7 +231,7 @@ amdgpu_connector_update_scratch_regs(struct drm_connector *connector,
 		if (connector->encoder_ids[i] == 0)
 			break;
 
-		encoder = drm_encoder_find(connector->dev,
+		encoder = drm_encoder_find(connector->dev, NULL,
 					connector->encoder_ids[i]);
 		if (!encoder)
 			continue;
@@ -256,7 +256,7 @@ amdgpu_connector_find_encoder(struct drm_connector *connector,
 	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
 		if (connector->encoder_ids[i] == 0)
 			break;
-		encoder = drm_encoder_find(connector->dev,
+		encoder = drm_encoder_find(connector->dev, NULL,
 					connector->encoder_ids[i]);
 		if (!encoder)
 			continue;
@@ -374,7 +374,7 @@ amdgpu_connector_best_single_encoder(struct drm_connector *connector)
 
 	/* pick the encoder ids */
 	if (enc_id)
-		return drm_encoder_find(connector->dev, enc_id);
+		return drm_encoder_find(connector->dev, NULL, enc_id);
 	return NULL;
 }
 
@@ -1079,7 +1079,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
 			if (connector->encoder_ids[i] == 0)
 				break;
 
-			encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+			encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
 			if (!encoder)
 				continue;
 
@@ -1136,7 +1136,7 @@ amdgpu_connector_dvi_encoder(struct drm_connector *connector)
 		if (connector->encoder_ids[i] == 0)
 			break;
 
-		encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+		encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
 		if (!encoder)
 			continue;
 
@@ -1155,7 +1155,7 @@ amdgpu_connector_dvi_encoder(struct drm_connector *connector)
 	/* then check use digitial */
 	/* pick the first one */
 	if (enc_id)
-		return drm_encoder_find(connector->dev, enc_id);
+		return drm_encoder_find(connector->dev, NULL, enc_id);
 	return NULL;
 }
 
@@ -1296,7 +1296,7 @@ u16 amdgpu_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *conn
 		if (connector->encoder_ids[i] == 0)
 			break;
 
-		encoder = drm_encoder_find(connector->dev,
+		encoder = drm_encoder_find(connector->dev, NULL,
 					connector->encoder_ids[i]);
 		if (!encoder)
 			continue;
@@ -1325,7 +1325,7 @@ static bool amdgpu_connector_encoder_is_hbr2(struct drm_connector *connector)
 	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
 		if (connector->encoder_ids[i] == 0)
 			break;
-		encoder = drm_encoder_find(connector->dev,
+		encoder = drm_encoder_find(connector->dev, NULL,
 					connector->encoder_ids[i]);
 		if (!encoder)
 			continue;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
index 0d2f060206dc..89382ee3c401 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -311,7 +311,7 @@ dce_virtual_encoder(struct drm_connector *connector)
 		if (connector->encoder_ids[i] == 0)
 			break;
 
-		encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+		encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
 		if (!encoder)
 			continue;
 
@@ -321,7 +321,7 @@ dce_virtual_encoder(struct drm_connector *connector)
 
 	/* pick the first one */
 	if (enc_id)
-		return drm_encoder_find(connector->dev, enc_id);
+		return drm_encoder_find(connector->dev, NULL, enc_id);
 	return NULL;
 }
 
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 3549a3356afe..987a89c21506 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -727,7 +727,7 @@ static struct drm_encoder *ast_best_single_encoder(struct drm_connector *connect
 	int enc_id = connector->encoder_ids[0];
 	/* pick the encoder ids */
 	if (enc_id)
-		return drm_encoder_find(connector->dev, enc_id);
+		return drm_encoder_find(connector->dev, NULL, enc_id);
 	return NULL;
 }
 
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
index 6a91e62da2f4..a24a18fbd65a 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -213,7 +213,7 @@ bochs_connector_best_encoder(struct drm_connector *connector)
 	int enc_id = connector->encoder_ids[0];
 	/* pick the encoder ids */
 	if (enc_id)
-		return drm_encoder_find(connector->dev, enc_id);
+		return drm_encoder_find(connector->dev, NULL, enc_id);
 	return NULL;
 }
 
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 53f6f0f84206..74d63b874443 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -496,7 +496,7 @@ static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector
 	int enc_id = connector->encoder_ids[0];
 	/* pick the encoder ids */
 	if (enc_id)
-		return drm_encoder_find(connector->dev, enc_id);
+		return drm_encoder_find(connector->dev, NULL, enc_id);
 	return NULL;
 }
 
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 01192dd3ed79..e92343b677b0 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -721,7 +721,7 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
 	struct drm_mode_config *config = &dev->mode_config;
 
 	if (property == config->prop_fb_id) {
-		struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, val);
+		struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val);
 		drm_atomic_set_fb_for_plane(state, fb);
 		if (fb)
 			drm_framebuffer_put(fb);
@@ -737,7 +737,7 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
 			return -EINVAL;
 
 	} else if (property == config->prop_crtc_id) {
-		struct drm_crtc *crtc = drm_crtc_find(dev, val);
+		struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val);
 		return drm_atomic_set_crtc_for_plane(state, crtc);
 	} else if (property == config->prop_crtc_x) {
 		state->crtc_x = U642I64(val);
@@ -1153,7 +1153,7 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
 	struct drm_mode_config *config = &dev->mode_config;
 
 	if (property == config->prop_crtc_id) {
-		struct drm_crtc *crtc = drm_crtc_find(dev, val);
+		struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val);
 		return drm_atomic_set_crtc_for_connector(state, crtc);
 	} else if (property == config->dpms_property) {
 		/* setting DPMS property requires special handling, which
@@ -2240,7 +2240,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
 			goto out;
 		}
 
-		obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_ANY);
+		obj = drm_mode_object_find(dev, file_priv, obj_id, DRM_MODE_OBJECT_ANY);
 		if (!obj) {
 			ret = -ENOENT;
 			goto out;
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 41f9d47d2bf6..8ecf639881d6 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3348,7 +3348,7 @@ struct drm_encoder *
 drm_atomic_helper_best_encoder(struct drm_connector *connector)
 {
 	WARN_ON(connector->encoder_ids[1]);
-	return drm_encoder_find(connector->dev, connector->encoder_ids[0]);
+	return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]);
 }
 EXPORT_SYMBOL(drm_atomic_helper_best_encoder);
 
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index fe0982708e95..0d002b045bd2 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -230,7 +230,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		return -EINVAL;
 
-	crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
+	crtc = drm_crtc_find(dev, file_priv, crtc_lut->crtc_id);
 	if (!crtc)
 		return -ENOENT;
 
@@ -308,7 +308,7 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev,
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		return -EINVAL;
 
-	crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
+	crtc = drm_crtc_find(dev, file_priv, crtc_lut->crtc_id);
 	if (!crtc)
 		return -ENOENT;
 
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 8072e6e4c62c..f8feb2bf142a 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1289,7 +1289,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
 
 	memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
 
-	connector = drm_connector_lookup(dev, out_resp->connector_id);
+	connector = drm_connector_lookup(dev, file_priv, out_resp->connector_id);
 	if (!connector)
 		return -ENOENT;
 
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5af25ce5bf7c..5dd2d28dd221 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -402,7 +402,7 @@ int drm_mode_getcrtc(struct drm_device *dev,
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		return -EINVAL;
 
-	crtc = drm_crtc_find(dev, crtc_resp->crtc_id);
+	crtc = drm_crtc_find(dev, file_priv, crtc_resp->crtc_id);
 	if (!crtc)
 		return -ENOENT;
 
@@ -569,7 +569,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 	if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
 		return -ERANGE;
 
-	crtc = drm_crtc_find(dev, crtc_req->crtc_id);
+	crtc = drm_crtc_find(dev, file_priv, crtc_req->crtc_id);
 	if (!crtc) {
 		DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
 		return -ENOENT;
@@ -595,7 +595,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 			/* Make refcounting symmetric with the lookup path. */
 			drm_framebuffer_get(fb);
 		} else {
-			fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
+			fb = drm_framebuffer_lookup(dev, file_priv, crtc_req->fb_id);
 			if (!fb) {
 				DRM_DEBUG_KMS("Unknown FB ID%d\n",
 						crtc_req->fb_id);
@@ -680,7 +680,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 				goto out;
 			}
 
-			connector = drm_connector_lookup(dev, out_id);
+			connector = drm_connector_lookup(dev, file_priv, out_id);
 			if (!connector) {
 				DRM_DEBUG_KMS("Connector id %d unknown\n",
 						out_id);
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index d077c5490041..140752f13bc1 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -106,6 +106,7 @@ int drm_mode_object_add(struct drm_device *dev, struct drm_mode_object *obj,
 void drm_mode_object_register(struct drm_device *dev,
 			      struct drm_mode_object *obj);
 struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
+					       struct drm_file *file_priv,
 					       uint32_t id, uint32_t type);
 void drm_mode_object_unregister(struct drm_device *dev,
 				struct drm_mode_object *object);
diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index 0708779840d2..43f644844b83 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -220,7 +220,7 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		return -EINVAL;
 
-	encoder = drm_encoder_find(dev, enc_resp->encoder_id);
+	encoder = drm_encoder_find(dev, file_priv, enc_resp->encoder_id);
 	if (!encoder)
 		return -ENOENT;
 
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index af279844d7ce..2affe53f3fda 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -381,7 +381,7 @@ int drm_mode_rmfb(struct drm_device *dev,
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		return -EINVAL;
 
-	fb = drm_framebuffer_lookup(dev, *id);
+	fb = drm_framebuffer_lookup(dev, file_priv, *id);
 	if (!fb)
 		return -ENOENT;
 
@@ -450,7 +450,7 @@ int drm_mode_getfb(struct drm_device *dev,
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		return -EINVAL;
 
-	fb = drm_framebuffer_lookup(dev, r->fb_id);
+	fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
 	if (!fb)
 		return -ENOENT;
 
@@ -515,7 +515,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		return -EINVAL;
 
-	fb = drm_framebuffer_lookup(dev, r->fb_id);
+	fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
 	if (!fb)
 		return -ENOENT;
 
@@ -688,12 +688,13 @@ EXPORT_SYMBOL(drm_framebuffer_init);
  * again, using drm_framebuffer_put().
  */
 struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
+					       struct drm_file *file_priv,
 					       uint32_t id)
 {
 	struct drm_mode_object *obj;
 	struct drm_framebuffer *fb = NULL;
 
-	obj = __drm_mode_object_find(dev, id, DRM_MODE_OBJECT_FB);
+	obj = __drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_FB);
 	if (obj)
 		fb = obj_to_fb(obj);
 	return fb;
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
index da9a9adbcc98..ccc3a35d2de2 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -105,6 +105,7 @@ void drm_mode_object_unregister(struct drm_device *dev,
 }
 
 struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
+					       struct drm_file *file_priv,
 					       uint32_t id, uint32_t type)
 {
 	struct drm_mode_object *obj = NULL;
@@ -127,7 +128,7 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
 
 /**
  * drm_mode_object_find - look up a drm object with static lifetime
- * @dev: drm device
+ * @file_priv: drm file
  * @id: id of the mode object
  * @type: type of the mode object
  *
@@ -136,11 +137,12 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
  * by callind drm_mode_object_put().
  */
 struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
+		struct drm_file *file_priv,
 		uint32_t id, uint32_t type)
 {
 	struct drm_mode_object *obj = NULL;
 
-	obj = __drm_mode_object_find(dev, id, type);
+	obj = __drm_mode_object_find(dev, file_priv, id, type);
 	return obj;
 }
 EXPORT_SYMBOL(drm_mode_object_find);
@@ -347,7 +349,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
 
 	drm_modeset_lock_all(dev);
 
-	obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
+	obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
 	if (!obj) {
 		ret = -ENOENT;
 		goto out;
@@ -395,7 +397,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
 
 	drm_modeset_lock_all(dev);
 
-	arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
+	arg_obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
 	if (!arg_obj) {
 		ret = -ENOENT;
 		goto out;
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 5dc8c4350602..462c244498e2 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -395,7 +395,7 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		return -EINVAL;
 
-	plane = drm_plane_find(dev, plane_resp->plane_id);
+	plane = drm_plane_find(dev, file_priv, plane_resp->plane_id);
 	if (!plane)
 		return -ENOENT;
 
@@ -584,7 +584,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
 	 * First, find the plane, crtc, and fb objects.  If not available,
 	 * we don't bother to call the driver.
 	 */
-	plane = drm_plane_find(dev, plane_req->plane_id);
+	plane = drm_plane_find(dev, file_priv, plane_req->plane_id);
 	if (!plane) {
 		DRM_DEBUG_KMS("Unknown plane ID %d\n",
 			      plane_req->plane_id);
@@ -592,14 +592,14 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
 	}
 
 	if (plane_req->fb_id) {
-		fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
+		fb = drm_framebuffer_lookup(dev, file_priv, plane_req->fb_id);
 		if (!fb) {
 			DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
 				      plane_req->fb_id);
 			return -ENOENT;
 		}
 
-		crtc = drm_crtc_find(dev, plane_req->crtc_id);
+		crtc = drm_crtc_find(dev, file_priv, plane_req->crtc_id);
 		if (!crtc) {
 			DRM_DEBUG_KMS("Unknown crtc ID %d\n",
 				      plane_req->crtc_id);
@@ -709,7 +709,7 @@ static int drm_mode_cursor_common(struct drm_device *dev,
 	if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
 		return -EINVAL;
 
-	crtc = drm_crtc_find(dev, req->crtc_id);
+	crtc = drm_crtc_find(dev, file_priv, req->crtc_id);
 	if (!crtc) {
 		DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
 		return -ENOENT;
@@ -823,7 +823,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
 	if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip)
 		return -EINVAL;
 
-	crtc = drm_crtc_find(dev, page_flip->crtc_id);
+	crtc = drm_crtc_find(dev, file_priv, page_flip->crtc_id);
 	if (!crtc)
 		return -ENOENT;
 
@@ -884,7 +884,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
 		goto out;
 	}
 
-	fb = drm_framebuffer_lookup(dev, page_flip->fb_id);
+	fb = drm_framebuffer_lookup(dev, file_priv, page_flip->fb_id);
 	if (!fb) {
 		ret = -ENOENT;
 		goto out;
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 904966cde32b..bc71660a32de 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -99,7 +99,7 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode,
 
 	/* Step 2: Validate against encoders and crtcs */
 	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
-		struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]);
+		struct drm_encoder *encoder = drm_encoder_find(dev, NULL, ids[i]);
 		struct drm_crtc *crtc;
 
 		if (!encoder)
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index bc5128203056..bae50e6b819d 100644
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -450,7 +450,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		return -EINVAL;
 
-	property = drm_property_find(dev, out_resp->prop_id);
+	property = drm_property_find(dev, file_priv, out_resp->prop_id);
 	if (!property)
 		return -ENOENT;
 
@@ -634,7 +634,7 @@ struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
 	struct drm_mode_object *obj;
 	struct drm_property_blob *blob = NULL;
 
-	obj = __drm_mode_object_find(dev, id, DRM_MODE_OBJECT_BLOB);
+	obj = __drm_mode_object_find(dev, NULL, id, DRM_MODE_OBJECT_BLOB);
 	if (obj)
 		blob = obj_to_blob(obj);
 	return blob;
@@ -897,7 +897,7 @@ bool drm_property_change_valid_get(struct drm_property *property,
 		if (value == 0)
 			return true;
 
-		*ref = __drm_mode_object_find(property->dev, value,
+		*ref = __drm_mode_object_find(property->dev, NULL, value,
 					      property->values[0]);
 		return *ref != NULL;
 	}
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index 12a18557c5fd..ffb7a731572e 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -36,7 +36,7 @@ static int hibmc_connector_mode_valid(struct drm_connector *connector,
 static struct drm_encoder *
 hibmc_connector_best_encoder(struct drm_connector *connector)
 {
-	return drm_encoder_find(connector->dev, connector->encoder_ids[0]);
+	return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]);
 }
 
 static const struct drm_connector_helper_funcs
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e92fd14c06c7..4d687d87109a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14055,7 +14055,7 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
 	struct drm_crtc *drmmode_crtc;
 	struct intel_crtc *crtc;
 
-	drmmode_crtc = drm_crtc_find(dev, pipe_from_crtc_id->crtc_id);
+	drmmode_crtc = drm_crtc_find(dev, file, pipe_from_crtc_id->crtc_id);
 	if (!drmmode_crtc)
 		return -ENOENT;
 
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index b96aed941b97..559fbbcf7504 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -1127,7 +1127,7 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
 	if (!params)
 		return -ENOMEM;
 
-	drmmode_crtc = drm_crtc_find(dev, put_image_rec->crtc_id);
+	drmmode_crtc = drm_crtc_find(dev, file_priv, put_image_rec->crtc_id);
 	if (!drmmode_crtc) {
 		ret = -ENOENT;
 		goto out_free;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 94f9a1332dbf..b80f371f930f 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -995,7 +995,7 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
 	    set->flags & I915_SET_COLORKEY_DESTINATION)
 		return -EINVAL;
 
-	plane = drm_plane_find(dev, set->plane_id);
+	plane = drm_plane_find(dev, file_priv, set->plane_id);
 	if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
 		return -ENOENT;
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index f4b53588e071..18db47ce96c1 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -1702,7 +1702,7 @@ static struct drm_encoder *mga_connector_best_encoder(struct drm_connector
 	int enc_id = connector->encoder_ids[0];
 	/* pick the encoder ids */
 	if (enc_id)
-		return drm_encoder_find(connector->dev, enc_id);
+		return drm_encoder_find(connector->dev, NULL, enc_id);
 	return NULL;
 }
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 147b22163f9f..0f58758c701f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -373,7 +373,7 @@ find_encoder(struct drm_connector *connector, int type)
 		if (!id)
 			break;
 
-		enc = drm_encoder_find(dev, id);
+		enc = drm_encoder_find(dev, NULL, id);
 		if (!enc)
 			continue;
 		nv_encoder = nouveau_encoder(enc);
@@ -441,7 +441,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector)
 		if (id == 0)
 			break;
 
-		encoder = drm_encoder_find(dev, id);
+		encoder = drm_encoder_find(dev, NULL, id);
 		if (!encoder)
 			continue;
 		nv_encoder = nouveau_encoder(encoder);
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index c31e660e35db..7d39ed63e5be 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -1456,7 +1456,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
 	header = radeon_get_ib_value(p, h_idx);
 	crtc_id = radeon_get_ib_value(p, h_idx + 5);
 	reg = R100_CP_PACKET0_GET_REG(header);
-	crtc = drm_crtc_find(p->rdev->ddev, crtc_id);
+	crtc = drm_crtc_find(p->rdev->ddev, p->filp, crtc_id);
 	if (!crtc) {
 		DRM_ERROR("cannot find crtc %d\n", crtc_id);
 		return -ENOENT;
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 97fd58e97043..c96b31950ca7 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -887,7 +887,7 @@ int r600_cs_common_vline_parse(struct radeon_cs_parser *p,
 	crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
 	reg = R600_CP_PACKET0_GET_REG(header);
 
-	crtc = drm_crtc_find(p->rdev->ddev, crtc_id);
+	crtc = drm_crtc_find(p->rdev->ddev, p->filp, crtc_id);
 	if (!crtc) {
 		DRM_ERROR("cannot find crtc %d\n", crtc_id);
 		return -ENOENT;
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 27affbde058c..5d4b6d46575e 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -263,7 +263,7 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c
 		if (connector->encoder_ids[i] == 0)
 			break;
 
-		encoder = drm_encoder_find(connector->dev,
+		encoder = drm_encoder_find(connector->dev, NULL,
 					   connector->encoder_ids[i]);
 		if (!encoder)
 			continue;
@@ -290,7 +290,7 @@ static struct drm_encoder *radeon_find_encoder(struct drm_connector *connector,
 		if (connector->encoder_ids[i] == 0)
 			break;
 
-		encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+		encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
 		if (!encoder)
 			continue;
 
@@ -404,7 +404,7 @@ static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *conn
 	int enc_id = connector->encoder_ids[0];
 	/* pick the encoder ids */
 	if (enc_id)
-		return drm_encoder_find(connector->dev, enc_id);
+		return drm_encoder_find(connector->dev, NULL, enc_id);
 	return NULL;
 }
 
@@ -1365,7 +1365,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
 			if (connector->encoder_ids[i] == 0)
 				break;
 
-			encoder = drm_encoder_find(connector->dev,
+			encoder = drm_encoder_find(connector->dev, NULL,
 						   connector->encoder_ids[i]);
 			if (!encoder)
 				continue;
@@ -1451,7 +1451,7 @@ static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
 		if (connector->encoder_ids[i] == 0)
 			break;
 
-		encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+		encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
 		if (!encoder)
 			continue;
 
@@ -1470,7 +1470,7 @@ static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
 	/* then check use digitial */
 	/* pick the first one */
 	if (enc_id)
-		return drm_encoder_find(connector->dev, enc_id);
+		return drm_encoder_find(connector->dev, NULL, enc_id);
 	return NULL;
 }
 
@@ -1617,7 +1617,7 @@ u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *conn
 		if (connector->encoder_ids[i] == 0)
 			break;
 
-		encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+		encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
 		if (!encoder)
 			continue;
 
@@ -1646,7 +1646,7 @@ static bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector)
 		if (connector->encoder_ids[i] == 0)
 			break;
 
-		encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+		encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
 		if (!encoder)
 			continue;
 
diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c
index d2f57c52f7db..59de243e5ffc 100644
--- a/drivers/gpu/drm/udl/udl_connector.c
+++ b/drivers/gpu/drm/udl/udl_connector.c
@@ -105,7 +105,7 @@ static struct drm_encoder*
 udl_best_single_encoder(struct drm_connector *connector)
 {
 	int enc_id = connector->encoder_ids[0];
-	return drm_encoder_find(connector->dev, enc_id);
+	return drm_encoder_find(connector->dev, NULL, enc_id);
 }
 
 static int udl_connector_set_property(struct drm_connector *connector,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
index 5ec24fd801cd..01be355525e4 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
@@ -286,7 +286,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data,
 
 	drm_modeset_lock_all(dev);
 
-	fb = drm_framebuffer_lookup(dev, arg->fb_id);
+	fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id);
 	if (!fb) {
 		DRM_ERROR("Invalid framebuffer id.\n");
 		ret = -ENOENT;
@@ -369,7 +369,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
 
 	drm_modeset_lock_all(dev);
 
-	fb = drm_framebuffer_lookup(dev, arg->fb_id);
+	fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id);
 	if (!fb) {
 		DRM_ERROR("Invalid framebuffer id.\n");
 		ret = -ENOENT;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 620180df1303..cc1d4f575795 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1693,7 +1693,7 @@ int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
 		return 0;
 	}
 
-	crtc = drm_crtc_find(dev, arg->crtc_id);
+	crtc = drm_crtc_find(dev, file_priv, arg->crtc_id);
 	if (!crtc) {
 		ret = -ENOENT;
 		goto out;
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 4bc088269d05..49bbaf320f46 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -935,10 +935,11 @@ static inline unsigned drm_connector_index(struct drm_connector *connector)
  * add takes a reference to it.
  */
 static inline struct drm_connector *drm_connector_lookup(struct drm_device *dev,
+		struct drm_file *file_priv,
 		uint32_t id)
 {
 	struct drm_mode_object *mo;
-	mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CONNECTOR);
+	mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_CONNECTOR);
 	return mo ? obj_to_connector(mo) : NULL;
 }
 
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 3a911a64c257..6520e81fffcb 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -954,10 +954,11 @@ struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx);
  * userspace interface should be done using &drm_property.
  */
 static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev,
-	uint32_t id)
+		struct drm_file *file_priv,
+		uint32_t id)
 {
 	struct drm_mode_object *mo;
-	mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CRTC);
+	mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_CRTC);
 	return mo ? obj_to_crtc(mo) : NULL;
 }
 
diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
index 8d8245ec0181..86db0da8bdcb 100644
--- a/include/drm/drm_encoder.h
+++ b/include/drm/drm_encoder.h
@@ -214,11 +214,12 @@ static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
  * drm_mode_object_find().
  */
 static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev,
+						   struct drm_file *file_priv,
 						   uint32_t id)
 {
 	struct drm_mode_object *mo;
 
-	mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
+	mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_ENCODER);
 
 	return mo ? obj_to_encoder(mo) : NULL;
 }
diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
index 5244f059d23a..a7719e0029bd 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -198,6 +198,7 @@ int drm_framebuffer_init(struct drm_device *dev,
 			 struct drm_framebuffer *fb,
 			 const struct drm_framebuffer_funcs *funcs);
 struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
+					       struct drm_file *file_priv,
 					       uint32_t id);
 void drm_framebuffer_remove(struct drm_framebuffer *fb);
 void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index a767b4a30a6d..b2f920b518e3 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -27,6 +27,7 @@
 struct drm_object_properties;
 struct drm_property;
 struct drm_device;
+struct drm_file;
 
 /**
  * struct drm_mode_object - base structure for modeset objects
@@ -113,6 +114,7 @@ struct drm_object_properties {
 	}
 
 struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
+					     struct drm_file *file_priv,
 					     uint32_t id, uint32_t type);
 void drm_mode_object_get(struct drm_mode_object *obj);
 void drm_mode_object_put(struct drm_mode_object *obj);
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 9ab3e7044812..4a7c93b00e4f 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -571,10 +571,11 @@ int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
  * drm_mode_object_find().
  */
 static inline struct drm_plane *drm_plane_find(struct drm_device *dev,
+		struct drm_file *file_priv,
 		uint32_t id)
 {
 	struct drm_mode_object *mo;
-	mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PLANE);
+	mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_PLANE);
 	return mo ? obj_to_plane(mo) : NULL;
 }
 
diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h
index 37355c623e6c..429d8218f740 100644
--- a/include/drm/drm_property.h
+++ b/include/drm/drm_property.h
@@ -312,10 +312,11 @@ drm_property_unreference_blob(struct drm_property_blob *blob)
  * This function looks up the property object specified by id and returns it.
  */
 static inline struct drm_property *drm_property_find(struct drm_device *dev,
+						     struct drm_file *file_priv,
 						     uint32_t id)
 {
 	struct drm_mode_object *mo;
-	mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PROPERTY);
+	mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_PROPERTY);
 	return mo ? obj_to_property(mo) : NULL;
 }
 
-- 
2.13.3

^ permalink raw reply related

* [PATCH 4/6] drm: Add drm_object lease infrastructure [v4]
From: Keith Packard @ 2017-10-05  6:13 UTC (permalink / raw)
  To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
In-Reply-To: <20171005061310.29919-1-keithp@keithp.com>

This provides new data structures to hold "lease" information about
drm mode setting objects, and provides for creating new drm_masters
which have access to a subset of the available drm resources.

An 'owner' is a drm_master which is not leasing the objects from
another drm_master, and hence 'owns' them.

A 'lessee' is a drm_master which is leasing objects from some other
drm_master. Each lessee holds the set of objects which it is leasing
from the lessor.

A 'lessor' is a drm_master which is leasing objects to another
drm_master. This is the same as the owner in the current code.

The set of objects any drm_master 'controls' is limited to the set of
objects it leases (for lessees) or all objects (for owners).

Objects not controlled by a drm_master cannot be modified through the
various state manipulating ioctls, and any state reported back to user
space will be edited to make them appear idle and/or unusable. For
instance, connectors always report 'disconnected', while encoders
report no possible crtcs or clones.

The full list of lessees leasing objects from an owner (either
directly, or indirectly through another lessee), can be searched from
an idr in the drm_master of the owner.

Changes for v2 as suggested by Daniel Vetter <daniel.vetter@ffwll.ch>:

* Sub-leasing has been disabled.

* BUG_ON for lock checking replaced with lockdep_assert_held

* 'change' ioctl has been removed.

* Leased objects can always be controlled by the lessor; the
  'mask_lease' flag has been removed

* Checking for leased status has been simplified, replacing
  the drm_lease_check function with drm_lease_held.

Changes in v3, some suggested by Dave Airlie <airlied@gmail.com>

* Add revocation. This allows leases to be effectively revoked by
  removing all of the objects they have access to. The lease itself
  hangs around as it's hanging off a file.

* Free the leases IDR when the master is destroyed

* _drm_lease_held should look at lessees, not lessor

* Allow non-master files to check for lease status

Changes in v4, suggested by Dave Airlie <airlied@gmail.com>

* Formatting and whitespace changes

Signed-off-by: Keith Packard <keithp@keithp.com>
---
 drivers/gpu/drm/Makefile      |   2 +-
 drivers/gpu/drm/drm_auth.c    |  29 +++-
 drivers/gpu/drm/drm_lease.c   | 379 ++++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_auth.h        |  20 +++
 include/drm/drm_lease.h       |  36 ++++
 include/drm/drm_mode_object.h |   1 +
 6 files changed, 465 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_lease.c
 create mode 100644 include/drm/drm_lease.h

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 24a066e1841c..3a47f5ae6f16 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -17,7 +17,7 @@ drm-y       :=	drm_auth.o drm_bufs.o drm_cache.o \
 		drm_encoder.o drm_mode_object.o drm_property.o \
 		drm_plane.o drm_color_mgmt.o drm_print.o \
 		drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
-		drm_syncobj.o
+		drm_syncobj.o drm_lease.o
 
 drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
 drm-$(CONFIG_DRM_VM) += drm_vm.o
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 7ff697389d74..541177c71d51 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -31,6 +31,7 @@
 #include <drm/drmP.h>
 #include "drm_internal.h"
 #include "drm_legacy.h"
+#include <drm/drm_lease.h>
 
 /**
  * DOC: master and authentication
@@ -93,7 +94,7 @@ int drm_authmagic(struct drm_device *dev, void *data,
 	return file ? 0 : -EINVAL;
 }
 
-static struct drm_master *drm_master_create(struct drm_device *dev)
+struct drm_master *drm_master_create(struct drm_device *dev)
 {
 	struct drm_master *master;
 
@@ -107,6 +108,14 @@ static struct drm_master *drm_master_create(struct drm_device *dev)
 	idr_init(&master->magic_map);
 	master->dev = dev;
 
+	/* initialize the tree of output resource lessees */
+	master->lessor = NULL;
+	master->lessee_id = 0;
+	INIT_LIST_HEAD(&master->lessees);
+	INIT_LIST_HEAD(&master->lessee_list);
+	idr_init(&master->leases);
+	idr_init(&master->lessee_idr);
+
 	return master;
 }
 
@@ -189,6 +198,12 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
 		goto out_unlock;
 	}
 
+	if (file_priv->master->lessor != NULL) {
+		DRM_DEBUG_LEASE("Attempt to set lessee %d as master\n", file_priv->master->lessee_id);
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
 	ret = drm_set_master(dev, file_priv, false);
 out_unlock:
 	mutex_unlock(&dev->master_mutex);
@@ -270,6 +285,13 @@ void drm_master_release(struct drm_file *file_priv)
 	if (dev->master == file_priv->master)
 		drm_drop_master(dev, file_priv);
 out:
+	if (file_priv->is_master) {
+		/* Revoke any leases held by this or lessees, but only if
+		 * this is the "real" master
+		 */
+		_drm_lease_revoke(master);
+	}
+
 	/* drop the master reference held by the file priv */
 	if (file_priv->master)
 		drm_master_put(&file_priv->master);
@@ -310,12 +332,17 @@ static void drm_master_destroy(struct kref *kref)
 	struct drm_master *master = container_of(kref, struct drm_master, refcount);
 	struct drm_device *dev = master->dev;
 
+	drm_lease_destroy(master);
+
 	if (dev->driver->master_destroy)
 		dev->driver->master_destroy(dev, master);
 
 	drm_legacy_master_rmmaps(dev, master);
 
 	idr_destroy(&master->magic_map);
+	idr_destroy(&master->leases);
+	idr_destroy(&master->lessee_idr);
+
 	kfree(master->unique);
 	kfree(master);
 }
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
new file mode 100644
index 000000000000..2ac404264d75
--- /dev/null
+++ b/drivers/gpu/drm/drm_lease.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * 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.
+ *
+ * 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 <drm/drmP.h>
+#include "drm_internal.h"
+#include "drm_legacy.h"
+#include "drm_crtc_internal.h"
+#include <drm/drm_lease.h>
+#include <drm/drm_auth.h>
+#include <drm/drm_crtc_helper.h>
+
+#define drm_for_each_lessee(lessee, lessor) \
+	list_for_each_entry((lessee), &(lessor)->lessees, lessee_list)
+
+/**
+ * drm_lease_owner - return ancestor owner drm_master
+ * @master: drm_master somewhere within tree of lessees and lessors
+ *
+ * RETURN:
+ *
+ * drm_master at the top of the tree (i.e, with lessor NULL
+ */
+struct drm_master *drm_lease_owner(struct drm_master *master)
+{
+	while (master->lessor != NULL)
+		master = master->lessor;
+	return master;
+}
+EXPORT_SYMBOL(drm_lease_owner);
+
+/**
+ * _drm_find_lessee - find lessee by id
+ * @master: drm_master of lessor
+ * @id: lessee_id
+ *
+ * RETURN:
+ *
+ * drm_master of the lessee if valid, NULL otherwise
+ */
+
+static struct drm_master*
+_drm_find_lessee(struct drm_master *master, int lessee_id)
+{
+	return idr_find(&drm_lease_owner(master)->lessee_idr, lessee_id);
+}
+
+/**
+ * _drm_lease_held_master - check to see if an object is leased (or owned) by master
+ * @master: the master to check the lease status of
+ * @id: the id to check
+ *
+ * Checks if the specified master holds a lease on the object. Return
+ * value:
+ *
+ *	true		'master' holds a lease on (or owns) the object
+ *	false		'master' does not hold a lease.
+ */
+static int _drm_lease_held_master(struct drm_master *master, int id)
+{
+	lockdep_assert_held(&master->dev->mode_config.idr_mutex);
+	if (master->lessor)
+		return idr_find(&master->leases, id) != NULL;
+	return true;
+}
+
+/**
+ * _drm_has_leased - check to see if an object has been leased
+ * @master: the master to check the lease status of
+ * @id: the id to check
+ *
+ * Checks if any lessee of 'master' holds a lease on 'id'. Return
+ * value:
+ *
+ *	true		Some lessee holds a lease on the object.
+ *	false		No lessee has a lease on the object.
+ */
+static bool _drm_has_leased(struct drm_master *master, int id)
+{
+	struct drm_master *lessee;
+
+	drm_for_each_lessee(lessee, master)
+		if (_drm_lease_held_master(lessee, id))
+			return true;
+	return false;
+}
+
+/**
+ * _drm_lease_held - check drm_mode_object lease status (idr_mutex held)
+ * @master: the drm_master
+ * @id: the object id
+ *
+ * Checks if the specified master holds a lease on the object. Return
+ * value:
+ *
+ *	true		'master' holds a lease on (or owns) the object
+ *	false		'master' does not hold a lease.
+ */
+bool _drm_lease_held(struct drm_file *file_priv, int id)
+{
+	if (file_priv == NULL || file_priv->master == NULL)
+		return true;
+
+	return _drm_lease_held_master(file_priv->master, id);
+}
+EXPORT_SYMBOL(_drm_lease_held);
+
+/**
+ * drm_lease_held - check drm_mode_object lease status (idr_mutex not held)
+ * @master: the drm_master
+ * @id: the object id
+ *
+ * Checks if the specified master holds a lease on the object. Return
+ * value:
+ *
+ *	true		'master' holds a lease on (or owns) the object
+ *	false		'master' does not hold a lease.
+ */
+bool drm_lease_held(struct drm_file *file_priv, int id)
+{
+	struct drm_master *master;
+	bool ret;
+
+	if (file_priv == NULL || file_priv->master == NULL)
+		return true;
+
+	master = file_priv->master;
+	mutex_lock(&master->dev->mode_config.idr_mutex);
+	ret = _drm_lease_held_master(master, id);
+	mutex_unlock(&master->dev->mode_config.idr_mutex);
+	return ret;
+}
+EXPORT_SYMBOL(drm_lease_held);
+
+/**
+ * drm_lease_filter_crtcs - restricted crtc set to leased values
+ * @file_priv: requestor file
+ * @crtcs: bitmask of crtcs to check
+ *
+ * Reconstructs a crtc mask based on the crtcs which are visible
+ * through the specified file.
+ */
+uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
+{
+	struct drm_master *master;
+	struct drm_device *dev;
+	struct drm_crtc *crtc;
+	int count_in, count_out;
+	uint32_t crtcs_out = 0;
+
+	if (file_priv == NULL || file_priv->master == NULL)
+		return crtcs_in;
+
+	master = file_priv->master;
+	dev = master->dev;
+
+	count_in = count_out = 0;
+	mutex_lock(&master->dev->mode_config.idr_mutex);
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		if (_drm_lease_held_master(master, crtc->base.id)) {
+			uint32_t mask_in = 1ul << count_in;
+			if ((crtcs_in & mask_in) != 0) {
+				uint32_t mask_out = 1ul << count_out;
+				crtcs_out |= mask_out;
+			}
+			count_out++;
+		}
+		count_in++;
+	}
+	mutex_unlock(&master->dev->mode_config.idr_mutex);
+	return crtcs_out;
+}
+EXPORT_SYMBOL(drm_lease_filter_crtcs);
+
+/**
+ * drm_lease_filter_encoders - restrict encoder set to leased values
+ * @file_priv: requestor file
+ * @encoders: bitmask of encoders to check
+ *
+ * Reconstructs an encoder mask based on the encoders which are
+ * visible through the specified file.
+ */
+uint32_t drm_lease_filter_encoders(struct drm_file *file_priv, uint32_t encoders_in)
+{
+	struct drm_master *master;
+	struct drm_device *dev;
+	struct drm_encoder *encoder;
+	int count_in, count_out;
+	uint32_t encoders_out = 0;
+
+	count_in = count_out = 0;
+	if (file_priv == NULL || file_priv->master == NULL)
+		return encoders_in;
+
+	master = file_priv->master;
+	dev = master->dev;
+
+	mutex_lock(&master->dev->mode_config.idr_mutex);
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		if (_drm_lease_held_master(master, encoder->base.id)) {
+			uint32_t mask_in = 1ul << count_in;
+			if ((encoders_in & mask_in) != 0) {
+				uint32_t mask_out = 1ul << count_out;
+				encoders_out |= mask_out;
+			}
+			count_out++;
+		}
+		count_in++;
+	}
+	mutex_unlock(&master->dev->mode_config.idr_mutex);
+	return encoders_out;
+}
+EXPORT_SYMBOL(drm_lease_filter_encoders);
+
+/*
+ * drm_lease_create - create a new drm_master with leased objects
+ * @lessor: lease holder (or owner) of objects
+ * @leases: objects to lease to the new drm_master
+ *
+ * Uses drm_master_create to allocate a new drm_master, then checks to
+ * make sure all of the desired objects can be leased, atomically
+ * leasing them to the new drmmaster.
+ *
+ * 	ERR_PTR(-EACCESS)	some other master holds the title to any object
+ * 	ERR_PTR(-ENOENT)	some object is not a valid DRM object for this device
+ * 	ERR_PTR(-EBUSY)		some other lessee holds title to this object
+ *	ERR_PTR(-EEXIST)	same object specified more than once in the provided list
+ *	ERR_PTR(-ENOMEM)	allocation failed
+ */
+static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr *leases)
+{
+	struct drm_device *dev = lessor->dev;
+	int error;
+	struct drm_master *lessee;
+	int object;
+	int id;
+	void *entry;
+
+	DRM_DEBUG_LEASE("lessor %d\n", lessor->lessee_id);
+
+	lockdep_assert_held(&lessor->dev->master_mutex);
+
+	lessee = drm_master_create(lessor->dev);
+	if (!lessee) {
+		DRM_DEBUG_LEASE("drm_master_create failed\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	/* Insert the new lessee into the tree */
+	id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL);
+	if (id < 0) {
+		error = id;
+		goto out_lessee;
+	}
+
+	lessee->lessee_id = id;
+	lessee->lessor = drm_master_get(lessor);
+	list_add_tail(&lessee->lessee_list, &lessor->lessees);
+
+	/* Lock the mode object mutex to make the check and allocation atomic */
+	mutex_lock(&lessor->dev->mode_config.idr_mutex);
+	idr_for_each_entry(leases, entry, object) {
+		error = 0;
+		if (!idr_find(&dev->mode_config.crtc_idr, object))
+			error = -ENOENT;
+		else if (!_drm_lease_held_master(lessor, object))
+			error = -EACCES;
+		else if (_drm_has_leased(lessor, object))
+			error = -EBUSY;
+
+		if (error != 0) {
+			DRM_DEBUG_LEASE("object %d failed %d\n", object, error);
+			goto out_unlock;
+		}
+	}
+
+	/* Move the leases over */
+	lessee->leases = *leases;
+	mutex_unlock(&lessor->dev->mode_config.idr_mutex);
+	DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor);
+	return lessee;
+
+out_unlock:
+	mutex_unlock(&lessor->dev->mode_config.idr_mutex);
+
+out_lessee:
+	drm_master_put(&lessee);
+	return ERR_PTR(error);
+}
+
+/**
+ * drm_lease_destroy - a master is going away
+ * @master: the drm_master being destroyed
+ *
+ * All lessees will have been destroyed as they
+ * hold a reference on their lessor. Notify any
+ * lessor for this master so that it can check
+ * the list of lessees.
+ */
+void drm_lease_destroy(struct drm_master *master)
+{
+	struct drm_device *dev = master->dev;
+
+	lockdep_assert_held(&dev->master_mutex);
+
+	DRM_DEBUG_LEASE("drm_lease_destroy %d\n", master->lessee_id);
+
+	/* This master is referenced by all lessees, hence it cannot be destroyed
+	 * until all of them have been
+	 */
+	WARN_ON(!list_empty(&master->lessees));
+
+	/* Remove this master from the lessee idr in the owner */
+	if (master->lessee_id != 0) {
+		DRM_DEBUG_LEASE("remove master %d from device list of lessees\n", master->lessee_id);
+		idr_remove(&(drm_lease_owner(master)->lessee_idr), master->lessee_id);
+	}
+
+	/* Remove this master from any lessee list it may be on */
+	list_del(&master->lessee_list);
+	if (master->lessor) {
+		/* Tell the master to check the lessee list */
+		drm_sysfs_hotplug_event(dev);
+		drm_master_put(&master->lessor);
+	}
+
+	DRM_DEBUG_LEASE("drm_lease_destroy done %d\n", master->lessee_id);
+}
+
+/**
+ * _drm_lease_revoke - revoke access to all leased objects
+ * @master: the master losing its lease
+ */
+
+void _drm_lease_revoke(struct drm_master *top)
+{
+	int object;
+	void *entry;
+	struct drm_master *master = top;
+
+	/*
+	 * Walk the tree starting at 'top' emptying all leases. Because
+	 * the tree is fully connected, we can do this without recursing
+	 */
+	for (;;) {
+		DRM_DEBUG_LEASE("revoke leases for %p %d\n", master, master->lessee_id);
+
+		/* Evacuate the lease */
+		idr_for_each_entry(&master->leases, entry, object)
+			idr_remove(&master->leases, object);
+
+		/* Depth-first list walk */
+
+		/* Down */
+		if (!list_empty(&master->lessees)) {
+			master = list_first_entry(&master->lessees, struct drm_master, lessee_list);
+		} else {
+			/* Up */
+			while (master != top && master == list_last_entry(&master->lessor->lessees, struct drm_master, lessee_list))
+				master = master->lessor;
+
+			if (master == top)
+				break;
+
+			/* Over */
+			master = list_entry(master->lessee_list.next, struct drm_master, lessee_list);
+		}
+	}
+}
diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
index 81a40c2a9a3e..4b7fc22d3fc9 100644
--- a/include/drm/drm_auth.h
+++ b/include/drm/drm_auth.h
@@ -52,6 +52,12 @@ struct drm_lock_data {
  * @dev: Link back to the DRM device
  * @lock: DRI1 lock information.
  * @driver_priv: Pointer to driver-private information.
+ * @lessor: Lease holder
+ * @lessee_id: id for lessees. Owners always have id 0
+ * @lessee_list: other lessees of the same master
+ * @lessees: drm_masters leasing from this one
+ * @leases: Objects leased to this drm_master.
+ * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
  *
  * Note that master structures are only relevant for the legacy/primary device
  * nodes, hence there can only be one per device, not one per drm_minor.
@@ -76,10 +82,24 @@ struct drm_master {
 	struct idr magic_map;
 	struct drm_lock_data lock;
 	void *driver_priv;
+
+	/* Tree of display resource leases, each of which is a drm_master struct
+	 * All of these get activated simultaneously, so drm_device master points
+	 * at the top of the tree (for which lessor is NULL)
+	 */
+
+	struct drm_master *lessor;
+	int	lessee_id;
+	struct list_head lessee_list;
+	struct list_head lessees;
+	struct idr leases;
+	struct idr lessee_idr;
 };
 
 struct drm_master *drm_master_get(struct drm_master *master);
 void drm_master_put(struct drm_master **master);
 bool drm_is_current_master(struct drm_file *fpriv);
 
+struct drm_master *drm_master_create(struct drm_device *dev);
+
 #endif
diff --git a/include/drm/drm_lease.h b/include/drm/drm_lease.h
new file mode 100644
index 000000000000..a49667db1d6d
--- /dev/null
+++ b/include/drm/drm_lease.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#ifndef _DRM_LEASE_H_
+#define _DRM_LEASE_H_
+
+struct drm_file;
+struct drm_device;
+struct drm_master;
+
+struct drm_master *drm_lease_owner(struct drm_master *master);
+
+void drm_lease_destroy(struct drm_master *lessee);
+
+bool drm_lease_held(struct drm_file *file_priv, int id);
+
+bool _drm_lease_held(struct drm_file *file_priv, int id);
+
+void _drm_lease_revoke(struct drm_master *master);
+
+uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs);
+
+uint32_t drm_lease_filter_encoders(struct drm_file *file_priv, uint32_t encoders);
+
+#endif /* _DRM_LEASE_H_ */
diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index b2f920b518e3..c8155cb5a932 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -24,6 +24,7 @@
 #define __DRM_MODESET_H__
 
 #include <linux/kref.h>
+#include <drm/drm_lease.h>
 struct drm_object_properties;
 struct drm_property;
 struct drm_device;
-- 
2.13.3

^ permalink raw reply related

* [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v4]
From: Keith Packard @ 2017-10-05  6:13 UTC (permalink / raw)
  To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
In-Reply-To: <20171005061310.29919-1-keithp@keithp.com>

drm_mode_create_lease

	Creates a lease for a list of drm mode objects, returning an
	fd for the new drm_master and a 64-bit identifier for the lessee

drm_mode_list_lesees

	List the identifiers of the lessees for a master file

drm_mode_get_lease

	List the leased objects for a master file

drm_mode_revoke_lease

	Erase the set of objects managed by a lease.

This should suffice to at least create and query leases.

Changes for v2 as suggested by Daniel Vetter <daniel.vetter@ffwll.ch>:

 * query ioctls only query the master associated with
   the provided file.

 * 'mask_lease' value has been removed

 * change ioctl has been removed.

Changes for v3 suggested in part by Dave Airlie <airlied@gmail.com>

 * Add revoke ioctl.

Changes for v3 suggested by Dave Airlie <airlied@gmail.com>

 * Expand on the comment about the magic use of &drm_lease_idr_object
 * Pad lease ioctl structures to align on 64-bit boundaries

Signed-off-by: Keith Packard <keithp@keithp.com>
---
 drivers/gpu/drm/drm_ioctl.c |   4 +
 drivers/gpu/drm/drm_lease.c | 277 ++++++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_lease.h     |  12 ++
 include/uapi/drm/drm.h      |   5 +
 include/uapi/drm/drm_mode.h |  66 +++++++++++
 5 files changed, 364 insertions(+)

diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 7d0e481c5729..3ed76220b4b1 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -657,6 +657,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl,
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 };
 
 #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index 2ac404264d75..e885ea76de8f 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -23,6 +23,8 @@
 #define drm_for_each_lessee(lessee, lessor) \
 	list_for_each_entry((lessee), &(lessor)->lessees, lessee_list)
 
+static uint64_t drm_lease_idr_object;
+
 /**
  * drm_lease_owner - return ancestor owner drm_master
  * @master: drm_master somewhere within tree of lessees and lessors
@@ -377,3 +379,278 @@ void _drm_lease_revoke(struct drm_master *top)
 		}
 	}
 }
+
+/**
+ * drm_mode_create_lease_ioctl - create a new lease
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_create_lease
+ * @file_priv: the file being manipulated
+ *
+ * The master associated with the specified file will have a lease
+ * created containing the objects specified in the ioctl structure.
+ * A file descriptor will be allocated for that and returned to the
+ * application.
+ */
+int drm_mode_create_lease_ioctl(struct drm_device *dev,
+				void *data, struct drm_file *lessor_priv)
+{
+	struct drm_mode_create_lease *cl = data;
+	size_t object_count;
+	size_t o;
+	int ret = 0;
+	struct idr leases;
+	struct drm_master *lessor = lessor_priv->master;
+	struct drm_master *lessee = NULL;
+	struct file *lessee_file = NULL;
+	struct file *lessor_file = lessor_priv->filp;
+	struct drm_file *lessee_priv;
+	int fd = -1;
+
+	/* Do not allow sub-leases */
+	if (lessor->lessor)
+		return -EINVAL;
+
+	object_count = cl->object_count;
+	idr_init(&leases);
+
+	/* Allocate a file descriptor for the lease */
+	fd = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK));
+
+	DRM_DEBUG_LEASE("Creating new lease\n");
+
+	/* Lookup the mode objects and add their IDs to the lease request */
+	for (o = 0; o < object_count; o++) {
+		__u32 object_id;
+
+		if (copy_from_user(&object_id,
+				   u64_to_user_ptr(cl->object_ids) + o * sizeof (__u32),
+				   sizeof (__u32))) {
+			ret = -EFAULT;
+			goto out_leases;
+		}
+		DRM_DEBUG_LEASE("Adding object %d to lease\n", object_id);
+
+		/*
+		 * We're using an IDR to hold the set of leased
+		 * objects, but we don't need to point at the object's
+		 * data structure from the lease as the main crtc_idr
+		 * will be used to actually find that. Instead, all we
+		 * really want is a 'leased/not-leased' result, for
+		 * which any non-NULL pointer will work fine.
+		 */
+		ret = idr_alloc(&leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);
+		if (ret < 0) {
+			DRM_DEBUG_LEASE("Object %d cannot be inserted into leases (%d)\n",
+					object_id, ret);
+			goto out_leases;
+		}
+	}
+
+	mutex_lock(&dev->master_mutex);
+
+	DRM_DEBUG_LEASE("Creating lease\n");
+	lessee = drm_lease_create(lessor, &leases);
+
+	if (IS_ERR(lessee)) {
+		ret = PTR_ERR(lessee);
+		mutex_unlock(&dev->master_mutex);
+		goto out_leases;
+	}
+
+	/* Clone the lessor file to create a new file for us */
+	DRM_DEBUG_LEASE("Allocating lease file\n");
+	path_get(&lessor_file->f_path);
+	lessee_file = alloc_file(&lessor_file->f_path,
+				 lessor_file->f_mode,
+				 fops_get(lessor_file->f_inode->i_fop));
+	mutex_unlock(&dev->master_mutex);
+
+	if (IS_ERR(lessee_file)) {
+		ret = PTR_ERR(lessee_file);
+		goto out_lessee;
+	}
+
+	/* Initialize the new file for DRM */
+	DRM_DEBUG_LEASE("Initializing the file with %p\n", lessee_file->f_op->open);
+	ret = lessee_file->f_op->open(lessee_file->f_inode, lessee_file);
+	if (ret)
+		goto out_lessee_file;
+
+	lessee_priv = lessee_file->private_data;
+
+	/* Change the file to a master one */
+	drm_master_put(&lessee_priv->master);
+	lessee_priv->master = lessee;
+	lessee_priv->is_master = 1;
+	lessee_priv->authenticated = 1;
+
+	/* Hook up the fd */
+	fd_install(fd, lessee_file);
+
+	/* Pass fd back to userspace */
+	DRM_DEBUG_LEASE("Returning fd %d id %d\n", fd, lessee->lessee_id);
+	cl->fd = fd;
+	cl->lessee_id = lessee->lessee_id;
+
+	DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n");
+	return 0;
+
+out_lessee_file:
+	fput(lessee_file);
+
+out_lessee:
+	drm_master_put(&lessee);
+
+out_leases:
+	idr_destroy(&leases);
+	put_unused_fd(fd);
+
+	DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret);
+	return ret;
+}
+
+/**
+ * drm_mode_list_lessees_ioctl - list lessee ids
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_list_lessees
+ * @lessor_priv: the file being manipulated
+ *
+ * Starting from the master associated with the specified file,
+ * the master with the provided lessee_id is found, and then
+ * an array of lessee ids associated with leases from that master
+ * are returned.
+ */
+
+int drm_mode_list_lessees_ioctl(struct drm_device *dev,
+			       void *data, struct drm_file *lessor_priv)
+{
+	struct drm_mode_list_lessees *arg = data;
+	__u32 __user *lessee_ids = (__u32 __user *) (uintptr_t) (arg->lessees_ptr);
+	__u32 count_lessees = arg->count_lessees;
+	struct drm_master *lessor = lessor_priv->master, *lessee;
+	int count;
+	int ret = 0;
+
+	DRM_DEBUG_LEASE("List lessees for %d\n", lessor->lessee_id);
+
+	mutex_lock(&dev->master_mutex);
+
+	count = 0;
+	drm_for_each_lessee(lessee, lessor) {
+		/* Only list un-revoked leases */
+		if (!idr_is_empty(&lessee->leases)) {
+			if (count_lessees > count) {
+				DRM_DEBUG_LEASE("Add lessee %d\n", lessee->lessee_id);
+				ret = put_user(lessee->lessee_id, lessee_ids + count);
+				if (ret)
+					break;
+			}
+			count++;
+		}
+	}
+
+	DRM_DEBUG_LEASE("Lessor leases to %d\n", count);
+	if (ret == 0)
+		arg->count_lessees = count;
+
+	mutex_unlock(&dev->master_mutex);
+
+	return ret;
+}
+
+/**
+ * drm_mode_get_lease_ioctl - list leased objects
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_get_lease
+ * @file_priv: the file being manipulated
+ *
+ * Return the list of leased objects for the specified lessee
+ */
+
+int drm_mode_get_lease_ioctl(struct drm_device *dev,
+			     void *data, struct drm_file *lessee_priv)
+{
+	struct drm_mode_get_lease *arg = data;
+	__u32 __user *object_ids = (__u32 __user *) (uintptr_t) (arg->objects_ptr);
+	__u32 count_objects = arg->count_objects;
+	struct drm_master *lessee = lessee_priv->master;
+	struct idr *object_idr;
+	int count;
+	void *entry;
+	int object;
+	int ret = 0;
+
+	DRM_DEBUG_LEASE("get lease for %d\n", lessee->lessee_id);
+
+	mutex_lock(&dev->master_mutex);
+
+	if (lessee->lessor == NULL)
+		/* owner can use all objects */
+		object_idr = &lessee->dev->mode_config.crtc_idr;
+	else
+		/* lessee can only use allowed object */
+		object_idr = &lessee->leases;
+
+	count = 0;
+	idr_for_each_entry(object_idr, entry, object) {
+		if (count_objects > count) {
+			DRM_DEBUG_LEASE("adding object %d\n", object);
+			ret = put_user(object, object_ids + count);
+			if (ret)
+				break;
+		}
+		count++;
+	}
+
+	DRM_DEBUG("lease holds %d objects\n", count);
+	if (ret == 0)
+		arg->count_objects = count;
+
+	mutex_unlock(&dev->master_mutex);
+
+	return ret;
+}
+
+/**
+ * drm_mode_revoke_lease_ioctl - revoke lease
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_revoke_lease
+ * @file_priv: the file being manipulated
+ *
+ * This removes all of the objects from the lease without
+ * actually getting rid of the lease itself; that way all
+ * references to it still work correctly
+ */
+int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
+				void *data, struct drm_file *lessor_priv)
+{
+	struct drm_mode_revoke_lease *arg = data;
+	struct drm_master *lessor = lessor_priv->master;
+	struct drm_master *lessee;
+	int ret = 0;
+
+	DRM_DEBUG_LEASE("revoke lease for %d\n", arg->lessee_id);
+
+	mutex_lock(&dev->master_mutex);
+
+	lessee = _drm_find_lessee(lessor, arg->lessee_id);
+
+	/* No such lessee */
+	if (!lessee) {
+		ret = -ENOENT;
+		goto fail;
+	}
+
+	/* Lease is not held by lessor */
+	if (lessee->lessor != lessor) {
+		ret = -EACCES;
+		goto fail;
+	}
+
+	_drm_lease_revoke(lessee);
+
+fail:
+	mutex_unlock(&dev->master_mutex);
+
+	return ret;
+}
diff --git a/include/drm/drm_lease.h b/include/drm/drm_lease.h
index a49667db1d6d..53ffcee2617e 100644
--- a/include/drm/drm_lease.h
+++ b/include/drm/drm_lease.h
@@ -33,4 +33,16 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs);
 
 uint32_t drm_lease_filter_encoders(struct drm_file *file_priv, uint32_t encoders);
 
+int drm_mode_create_lease_ioctl(struct drm_device *dev,
+				void *data, struct drm_file *file_priv);
+
+int drm_mode_list_lessees_ioctl(struct drm_device *dev,
+				void *data, struct drm_file *file_priv);
+
+int drm_mode_get_lease_ioctl(struct drm_device *dev,
+			     void *data, struct drm_file *file_priv);
+
+int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
+				void *data, struct drm_file *file_priv);
+
 #endif /* _DRM_LEASE_H_ */
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 101593ab10ac..dd350bf0ad75 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -841,6 +841,11 @@ extern "C" {
 #define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD	DRM_IOWR(0xC1, struct drm_syncobj_handle)
 #define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE	DRM_IOWR(0xC2, struct drm_syncobj_handle)
 
+#define DRM_IOCTL_MODE_CREATE_LEASE	DRM_IOWR(0xC3, struct drm_mode_create_lease)
+#define DRM_IOCTL_MODE_LIST_LESSEES	DRM_IOWR(0xC4, struct drm_mode_list_lessees)
+#define DRM_IOCTL_MODE_GET_LEASE	DRM_IOWR(0xC5, struct drm_mode_get_lease)
+#define DRM_IOCTL_MODE_REVOKE_LEASE	DRM_IOWR(0xC6, struct drm_mode_revoke_lease)
+
 /**
  * Device specific ioctls should only be in their respective headers
  * The device specific ioctl range is from 0x40 to 0x9f.
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 403339f98a92..5964f25fa88e 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -732,6 +732,72 @@ struct drm_mode_destroy_blob {
 	__u32 blob_id;
 };
 
+/**
+ * Lease mode resources, creating another drm_master.
+ */
+struct drm_mode_create_lease {
+	/** Pointer to array of object ids (__u32) */
+	__u64 object_ids;
+	/** Number of object ids */
+	__u32 object_count;
+	/** flags for new FD (O_CLOEXEC, etc) */
+	__u32 flags;
+
+	/** Return: unique identifier for lessee. */
+	__u32 lessee_id;
+	/** Return: file descriptor to new drm_master file */
+	__u32 fd;
+};
+
+/**
+ * List lesses from a drm_master
+ */
+struct drm_mode_list_lessees {
+	/** Number of lessees.
+	 * On input, provides length of the array.
+	 * On output, provides total number. No
+	 * more than the input number will be written
+	 * back, so two calls can be used to get
+	 * the size and then the data.
+	 */
+	__u32 count_lessees;
+	__u32 pad;
+
+	/** Pointer to lessees.
+	 * pointer to __u64 array of lessee ids
+	 */
+	__u64 lessees_ptr;
+};
+
+/**
+ * Get leased objects
+ */
+struct drm_mode_get_lease {
+	/** Number of leased objects.
+	 * On input, provides length of the array.
+	 * On output, provides total number. No
+	 * more than the input number will be written
+	 * back, so two calls can be used to get
+	 * the size and then the data.
+	 */
+	__u32 count_objects;
+	__u32 pad;
+
+	/** Pointer to objects.
+	 * pointer to __u32 array of object ids
+	 */
+	__u64 objects_ptr;
+};
+
+/**
+ * Revoke lease
+ */
+struct drm_mode_revoke_lease {
+	/** Unique ID of lessee
+	 */
+	__u32 lessee_id;
+};
+
 #if defined(__cplusplus)
 }
 #endif
-- 
2.13.3

^ permalink raw reply related

* [PATCH 3/6] drm: Add new LEASE debug level
From: Keith Packard @ 2017-10-05  6:13 UTC (permalink / raw)
  To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
In-Reply-To: <20171005061310.29919-1-keithp@keithp.com>

Separate out lease debugging from the core.

Signed-off-by: Keith Packard <keithp@keithp.com>
---
 drivers/gpu/drm/drm_drv.c | 3 ++-
 include/drm/drmP.h        | 4 ++++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 2ed2d919beae..f390b30f5906 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -57,7 +57,8 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug cat
 "\t\tBit 2 (0x04) will enable KMS messages (modesetting code)\n"
 "\t\tBit 3 (0x08) will enable PRIME messages (prime code)\n"
 "\t\tBit 4 (0x10) will enable ATOMIC messages (atomic code)\n"
-"\t\tBit 5 (0x20) will enable VBL messages (vblank code)");
+"\t\tBit 5 (0x20) will enable VBL messages (vblank code)\n"
+"\t\tBit 7 (0x80) will enable LEASE messages (leasing code)");
 module_param_named(debug, drm_debug, int, 0600);
 
 static DEFINE_SPINLOCK(drm_minor_lock);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 3aa3809ab524..2a54ccb16232 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -145,6 +145,7 @@ struct pci_controller;
 #define DRM_UT_ATOMIC		0x10
 #define DRM_UT_VBL		0x20
 #define DRM_UT_STATE		0x40
+#define DRM_UT_LEASE		0x80
 
 /***********************************************************************/
 /** \name DRM template customization defaults */
@@ -259,6 +260,9 @@ struct pci_controller;
 #define DRM_DEBUG_VBL(fmt, ...)					\
 	drm_printk(KERN_DEBUG, DRM_UT_VBL, fmt, ##__VA_ARGS__)
 
+#define DRM_DEBUG_LEASE(fmt, ...)					\
+	drm_printk(KERN_DEBUG, DRM_UT_LEASE, fmt, ##__VA_ARGS__)
+
 #define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, level, fmt, args...)	\
 ({									\
 	static DEFINE_RATELIMIT_STATE(_rs,				\
-- 
2.13.3

^ permalink raw reply related


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.