All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v2 2/2] ARM: dts: imx6q: Add mccmon6 board support
From: Lukasz Majewski @ 2017-01-03  6:02 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Rob Herring, Mark Rutland, Russell King, Fabio Estevam,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Vladimir Zapolskiy, Sascha Hauer, Zerlauth Karl (LWN),
	Lukasz Majewski
In-Reply-To: <20170103020650.GM20956@dragon>

Hi Shawn,

Thank you for your comments.

> On Tue, Jan 03, 2017 at 12:43:38AM +0100, Lukasz Majewski wrote:
> > From: Lukasz Majewski <l.majewski-AM3owJQeAb5mR6Xm/wNWPw@public.gmane.org>
> > 
> > This patch provides support for Liebherr's Monitor 6 board
> > (abverrated as mccmon6) to Linux kernel.
> > 
> > Signed-off-by: Lukasz Majewski <lukma-ynQEQJNshbs@public.gmane.org>
> > ---
> > Changes for v2:
> > - Reorganize the dts file according to Valdimir Zapolskiy's comments
> > 
> > ---
> > MCCMON6 board support depends on following patches:
> > 
> > 1. "video: backlight: pwm_bl: Initialize fb_bl_on[x] and use_count
> > during pwm_backlight_probe()"
> > http://patchwork.ozlabs.org/patch/708844/
> > 
> > 2. "pwm: imx: Provide atomic operation for IMX PWM driver"
> > 	http://patchwork.ozlabs.org/patch/708847/ -
> > http://patchwork.ozlabs.org/patch/708843/ ---
> >  arch/arm/boot/dts/Makefile          |   1 +
> >  arch/arm/boot/dts/imx6q-mccmon6.dts | 477
> > ++++++++++++++++++++++++++++++++++++ 2 files changed, 478
> > insertions(+) create mode 100644 arch/arm/boot/dts/imx6q-mccmon6.dts
> > 
> > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > index c558ba7..0aa8e89 100644
> > --- a/arch/arm/boot/dts/Makefile
> > +++ b/arch/arm/boot/dts/Makefile
> > @@ -383,6 +383,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
> >  	imx6q-hummingboard.dtb \
> >  	imx6q-icore-rqs.dtb \
> >  	imx6q-marsboard.dtb \
> > +	imx6q-mccmon6.dtb \
> >  	imx6q-nitrogen6x.dtb \
> >  	imx6q-nitrogen6_max.dtb \
> >  	imx6q-novena.dtb \
> > diff --git a/arch/arm/boot/dts/imx6q-mccmon6.dts
> > b/arch/arm/boot/dts/imx6q-mccmon6.dts new file mode 100644
> > index 0000000..7128dc2
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/imx6q-mccmon6.dts
> > @@ -0,0 +1,477 @@
> > +/*
> > + * Copyright 2016-2017
> > + * Lukasz Majewski, DENX Software Engineering, lukma-ynQEQJNshbs@public.gmane.org
> > + *
> > + * This program is free software; you can redistribute it and/or
> > modify
> > + * it under the terms of the GNU General Public License version 2
> > as
> > + * published by the Free Software Foundation.
> > + *
> > + */
> 
> You might want to GPL/X11 dual licence for non-Linux device tree
> users. There are a plenty of examples in arch/arm/boot/dts.  But note
> the following correction.
> 
> https://patchwork.kernel.org/patch/9475057/

For this board GPLv2 is enough. Is the above description correct or do
I need to add something?

> 
> > +
> > +/dts-v1/;
> > +
> > +#include "imx6q.dtsi"
> > +
> > +#include <dt-bindings/gpio/gpio.h>
> > +#include <dt-bindings/pwm/pwm.h>
> > +
> > +/ {
> > +	model = "Liebherr (LWN) monitor6 i.MX6 Quad Board";
> > +	compatible = "lwn,mccmon6", "fsl,imx6q";
> > +
> > +	memory {
> > +		reg = <0x10000000 0x80000000>;
> > +	};
> > +
> > +	backlight_lvds: backlight {
> > +		compatible = "pwm-backlight";
> > +		pinctrl-names = "default";
> > +		pinctrl-0 = <&pinctrl_backlight>;
> > +		pwms = <&pwm2 0 5000000 PWM_POLARITY_INVERTED>;
> > +		brightness-levels = <  0   1   2   3   4   5   6
> > 7   8   9
> > +				      10  11  12  13  14  15  16
> > 17  18  19
> > +				      20  21  22  23  24  25  26
> > 27  28  29
> > +				      30  31  32  33  34  35  36
> > 37  38  39
> > +				      40  41  42  43  44  45  46
> > 47  48  49
> > +				      50  51  52  53  54  55  56
> > 57  58  59
> > +				      60  61  62  63  64  65  66
> > 67  68  69
> > +				      70  71  72  73  74  75  76
> > 77  78  79
> > +				      80  81  82  83  84  85  86
> > 87  88  89
> > +				      90  91  92  93  94  95  96
> > 97  98  99
> > +				     100 101 102 103 104 105 106
> > 107 108 109
> > +				     110 111 112 113 114 115 116
> > 117 118 119
> > +				     120 121 122 123 124 125 126
> > 127 128 129
> > +				     130 131 132 133 134 135 136
> > 137 138 139
> > +				     140 141 142 143 144 145 146
> > 147 148 149
> > +				     150 151 152 153 154 155 156
> > 157 158 159
> > +				     160 161 162 163 164 165 166
> > 167 168 169
> > +				     170 171 172 173 174 175 176
> > 177 178 179
> > +				     180 181 182 183 184 185 186
> > 187 188 189
> > +				     190 191 192 193 194 195 196
> > 197 198 199
> > +				     200 201 202 203 204 205 206
> > 207 208 209
> > +				     210 211 212 213 214 215 216
> > 217 218 219
> > +				     220 221 222 223 224 225 226
> > 227 228 229
> > +				     230 231 232 233 234 235 236
> > 237 238 239
> > +				     240 241 242 243 244 245 246
> > 247 248 249
> > +				     250 251 252 253 254 255>;
> > +		default-brightness-level = <50>;
> > +		enable-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
> > +	};
> > +
> > +	reg_lvds: regulator-lvds {
> > +		compatible = "regulator-fixed";
> > +		regulator-name = "lvds_ppen";
> > +		regulator-min-microvolt = <3300000>;
> > +		regulator-max-microvolt = <3300000>;
> > +		regulator-boot-on;
> > +		pinctrl-names = "default";
> > +		pinctrl-0 = <&pinctrl_reg_lvds>;
> > +		gpio = <&gpio1 19 GPIO_ACTIVE_HIGH>;
> > +		enable-active-high;
> > +	};
> > +
> > +	panel-lvds0 {
> > +		compatible = "innolux,g121x1-l03";
> > +		backlight = <&backlight_lvds>;
> > +		power-supply = <&reg_lvds>;
> > +
> > +		port {
> > +			panel_in_lvds0: endpoint {
> > +				remote-endpoint = <&lvds0_out>;
> > +			};
> > +		};
> > +	};
> > +};
> > +
> > +&iomuxc {
> 
> Considering the data amount of this node, we generally put it at the
> bottom of the file to improve the readability of the rest.

But then it will not be alphabetically ordered :-).

I can put it on the end - no problem.

> 
> > +	pinctrl-names = "default";
> > +
> > +	imx6q-mccmon6 {
> 
> This container node can now be dropped completely to save one level of
> indentation.

Ok, I will remove imx6q-mccmon6 container node completely.

> 
> > +		pinctrl_backlight: dispgrp {
> > +			fsl,pins = <
> > +				/* BLEN_OUT */
> > +				MX6QDL_PAD_GPIO_2__GPIO1_IO02
> > 0x1b0b0
> > +			>;
> > +		};
> > +
> > +		pinctrl_ecspi3: ecspi3grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO	0x100b1
> > +
> > MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI	0x100b1
> > +
> > MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK	0x100b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_ecspi3_cs: ecspi3cs {
> 
> ecspi3csgrp, if we follow the naming scheme used in other nodes.
> 
> > +			fsl,pins = <
> > +				MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24
> > 0x80000000
> > +			>;
> > +		};
> > +
> > +		pinctrl_ecspi3_flwp: ecspi3flwp {
> 
> Ditto
> 
> > +			fsl,pins = <
> > +				MX6QDL_PAD_DISP0_DAT6__GPIO4_IO27
> > 0x80000000
> > +			>;
> > +		};
> > +
> > +		pinctrl_enet: enetgrp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_ENET_MDIO__ENET_MDIO		0x1b0b0
> > +
> > MX6QDL_PAD_ENET_MDC__ENET_MDC		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_TXC__RGMII_TXC		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_TD0__RGMII_TD0		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_TD1__RGMII_TD1		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_TD2__RGMII_TD2		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_TD3__RGMII_TD3		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	0x1b0b0
> > +
> > MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK	0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_RXC__RGMII_RXC		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_RD0__RGMII_RD0		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_RD1__RGMII_RD1		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_RD2__RGMII_RD2		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_RD3__RGMII_RD3		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	0x1b0b0
> > +				MX6QDL_PAD_GPIO_16__ENET_REF_CLK
> > 0x4001b0a8
> > +
> > MX6QDL_PAD_GPIO_6__ENET_IRQ		0x000b1
> > +
> > MX6QDL_PAD_ENET_RXD0__GPIO1_IO27        0x1b0b0
> > +			>;
> > +		};
> > +
> > +		pinctrl_i2c1: i2c1grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_CSI0_DAT9__I2C1_SCL	0x4001b8b1
> > +
> > MX6QDL_PAD_CSI0_DAT8__I2C1_SDA	0x4001b8b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_i2c2: i2c2grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_KEY_COL3__I2C2_SCL	0x4001b8b1
> > +
> > MX6QDL_PAD_KEY_ROW3__I2C2_SDA	0x4001b8b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_pwm2: pwm2grp {
> > +			fsl,pins = <
> > +				MX6QDL_PAD_GPIO_1__PWM2_OUT
> > 0x1b0b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_reg_lvds: req_lvds_grp {
> 
> reglvdsgrp
> 
> > +			fsl,pins = <
> > +				/* LVDS_PPEN_OUT */
> > +
> > MX6QDL_PAD_SD1_DAT2__GPIO1_IO19         0x1b0b0
> > +			>;
> > +		};
> > +
> > +		pinctrl_uart1: uart1grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA	0x1b0b1
> > +
> > MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA	0x1b0b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_uart4: uart4grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_KEY_COL0__UART4_TX_DATA	0x1b0b1
> > +
> > MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA	0x1b0b1
> > +
> > MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B	0x1b0b1
> > +
> > MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B	0x1b0b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_usdhc2: usdhc2grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_SD2_CMD__SD2_CMD		0x17059
> > +
> > MX6QDL_PAD_SD2_CLK__SD2_CLK		0x10059
> > +
> > MX6QDL_PAD_SD2_DAT0__SD2_DATA0		0x17059
> > +
> > MX6QDL_PAD_SD2_DAT1__SD2_DATA1		0x17059
> > +
> > MX6QDL_PAD_SD2_DAT2__SD2_DATA2		0x17059
> > +
> > MX6QDL_PAD_SD2_DAT3__SD2_DATA3		0x17059
> > +
> > MX6QDL_PAD_GPIO_4__GPIO1_IO04           0x1b0b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_usdhc3: usdhc3grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_SD3_CMD__SD3_CMD		0x17059
> > +
> > MX6QDL_PAD_SD3_CLK__SD3_CLK		0x10059
> > +
> > MX6QDL_PAD_SD3_DAT0__SD3_DATA0		0x17059
> > +
> > MX6QDL_PAD_SD3_DAT1__SD3_DATA1		0x17059
> > +
> > MX6QDL_PAD_SD3_DAT2__SD3_DATA2		0x17059
> > +
> > MX6QDL_PAD_SD3_DAT3__SD3_DATA3		0x17059
> > +
> > MX6QDL_PAD_SD3_DAT4__SD3_DATA4		0x17059
> > +
> > MX6QDL_PAD_SD3_DAT5__SD3_DATA5		0x17059
> > +
> > MX6QDL_PAD_SD3_DAT6__SD3_DATA6		0x17059
> > +
> > MX6QDL_PAD_SD3_DAT7__SD3_DATA7		0x17059
> > +
> > MX6QDL_PAD_SD3_RST__SD3_RESET		0x17059
> > +			>;
> > +		};
> > +
> > +		pinctrl_weim_cs0: weimcs0grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_EIM_CS0__EIM_CS0_B		0xb0b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_weim_nor: weimnorgrp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_EIM_OE__EIM_OE_B		0xb0b1
> > +
> > MX6QDL_PAD_EIM_RW__EIM_RW		0xb0b1
> > +
> > MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B	0xb060
> > +
> > MX6QDL_PAD_EIM_D16__EIM_DATA16		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D17__EIM_DATA17		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D18__EIM_DATA18		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D19__EIM_DATA19		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D20__EIM_DATA20		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D21__EIM_DATA21		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D22__EIM_DATA22		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D23__EIM_DATA23		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D24__EIM_DATA24		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D25__EIM_DATA25		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D26__EIM_DATA26		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D27__EIM_DATA27		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D28__EIM_DATA28		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D29__EIM_DATA29		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D30__EIM_DATA30		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D31__EIM_DATA31		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_A23__EIM_ADDR23		0xb0b1
> > +
> > MX6QDL_PAD_EIM_A22__EIM_ADDR22		0xb0b1
> > +
> > MX6QDL_PAD_EIM_A21__EIM_ADDR21		0xb0b1
> > +
> > MX6QDL_PAD_EIM_A20__EIM_ADDR20		0xb0b1
> > +
> > MX6QDL_PAD_EIM_A19__EIM_ADDR19		0xb0b1
> > +
> > MX6QDL_PAD_EIM_A18__EIM_ADDR18		0xb0b1
> > +
> > MX6QDL_PAD_EIM_A17__EIM_ADDR17		0xb0b1
> > +
> > MX6QDL_PAD_EIM_A16__EIM_ADDR16		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA15__EIM_AD15		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA14__EIM_AD14		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA13__EIM_AD13		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA12__EIM_AD12		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA11__EIM_AD11		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA10__EIM_AD10		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA9__EIM_AD09		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA8__EIM_AD08		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA7__EIM_AD07		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA6__EIM_AD06		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA5__EIM_AD05		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA4__EIM_AD04		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA3__EIM_AD03		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA2__EIM_AD02		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA1__EIM_AD01		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA0__EIM_AD00		0xb0b1
> > +			>;
> > +		};
> > +	};
> > +};
> > +
> > +&ecspi3 {
> > +	cs-gpios = <&gpio4 24 0>;
> 
> GPIO_ACTIVE_HIGH?

No, on our HW it is GPIO_ACTIVE_LOW

> 
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_ecspi3 &pinctrl_ecspi3_cs
> > &pinctrl_ecspi3_flwp>;
> > +	status = "okay";
> > +
> > +	flash: s25sl032p@0 {
> 
> Node name should be as generic as possible, while label name can be
> specific.  That said, 's25sl032p: flash@0' should be better.

OK.

> 
> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +		compatible = "spansion,s25sl032p", "jedec,spi-nor";
> 
> "spansion,s25sl032p" doesn't seem to be documented.  Can it be
> dropped?

This memory is jedec compatible and uses "jedec,spi-nor", so
"spansion,s25sl032p" can be dropped

> 
> > +		spi-max-frequency = <40000000>;
> > +		reg = <0>;
> > +	};
> > +};
> > +
> > +&fec {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_enet>;
> > +	phy-mode = "rgmii";
> > +	phy-reset-gpios = <&gpio1 27 0>;
> 
> GPIO_ACTIVE_xxx?  But you probably need GPIO_ACTIVE_LOW.

Yes.

> 
> > +	interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
> > +			      <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
> > +	status = "okay";
> > +};
> > +
> > +&i2c1 {
> > +	clock-frequency = <100000>;
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_i2c1>;
> > +	status = "okay";
> > +};
> > +
> > +&i2c2 {
> > +	clock-frequency = <100000>;
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_i2c2>;
> > +	status = "okay";
> > +
> > +	pmic: pfuze100@08 {
> 
> pfuze100: pmic@08
> 
> > +		compatible = "fsl,pfuze100";
> > +		reg = <0x08>;
> > +
> > +		regulators {
> > +			sw1a_reg: sw1ab {
> > +				regulator-min-microvolt = <300000>;
> > +				regulator-max-microvolt =
> > <1875000>;
> > +				regulator-boot-on;
> > +				regulator-always-on;
> > +				regulator-ramp-delay = <6250>;
> > +			};
> > +
> > +			sw1c_reg: sw1c {
> > +				regulator-min-microvolt = <300000>;
> > +				regulator-max-microvolt =
> > <1875000>;
> > +				regulator-boot-on;
> > +				regulator-always-on;
> > +				regulator-ramp-delay = <6250>;
> > +			};
> > +
> > +			sw2_reg: sw2 {
> > +				regulator-min-microvolt = <800000>;
> > +				regulator-max-microvolt =
> > <3950000>;
> > +				regulator-boot-on;
> > +				regulator-always-on;
> > +			};
> > +
> > +			sw3a_reg: sw3a {
> > +				regulator-min-microvolt = <400000>;
> > +				regulator-max-microvolt =
> > <1975000>;
> > +				regulator-boot-on;
> > +				regulator-always-on;
> > +			};
> > +
> > +			sw3b_reg: sw3b {
> > +				regulator-min-microvolt = <400000>;
> > +				regulator-max-microvolt =
> > <1975000>;
> > +				regulator-boot-on;
> > +				regulator-always-on;
> > +			};
> > +
> > +			sw4_reg: sw4 {
> > +				regulator-min-microvolt = <800000>;
> > +				regulator-max-microvolt =
> > <3300000>;
> > +			};
> > +
> > +			swbst_reg: swbst {
> > +				regulator-min-microvolt =
> > <5000000>;
> > +				regulator-max-microvolt =
> > <5150000>;
> > +			};
> > +
> > +			snvs_reg: vsnvs {
> > +				regulator-min-microvolt =
> > <1000000>;
> > +				regulator-max-microvolt =
> > <3000000>;
> > +				regulator-boot-on;
> > +				regulator-always-on;
> > +			};
> > +
> > +			vref_reg: vrefddr {
> > +				regulator-boot-on;
> > +				regulator-always-on;
> > +			};
> > +
> > +			vgen1_reg: vgen1 {
> > +				regulator-min-microvolt = <800000>;
> > +				regulator-max-microvolt =
> > <1550000>;
> > +			};
> > +
> > +			vgen2_reg: vgen2 {
> > +				regulator-min-microvolt = <800000>;
> > +				regulator-max-microvolt =
> > <1550000>;
> > +			};
> > +
> > +			vgen3_reg: vgen3 {
> > +				regulator-min-microvolt =
> > <1800000>;
> > +				regulator-max-microvolt =
> > <3300000>;
> > +			};
> > +
> > +			vgen4_reg: vgen4 {
> > +				regulator-min-microvolt =
> > <1800000>;
> > +				regulator-max-microvolt =
> > <3300000>;
> > +				regulator-always-on;
> > +			};
> > +
> > +			vgen5_reg: vgen5 {
> > +				regulator-min-microvolt =
> > <1800000>;
> > +				regulator-max-microvolt =
> > <3300000>;
> > +				regulator-always-on;
> > +			};
> > +
> > +			vgen6_reg: vgen6 {
> > +				regulator-min-microvolt =
> > <1800000>;
> > +				regulator-max-microvolt =
> > <3300000>;
> > +				regulator-always-on;
> > +			};
> > +		};
> > +	};
> > +};
> > +
> > +&ldb {
> > +	status = "okay";
> > +
> > +	lvds0: lvds-channel@0 {
> > +		fsl,data-mapping = "spwg";
> > +		fsl,data-width = <24>;
> > +		status = "okay";
> > +
> > +		port@4 {
> > +			reg = <4>;
> > +
> > +			lvds0_out: endpoint {
> > +				remote-endpoint =
> > <&panel_in_lvds0>;
> > +			};
> > +		};
> > +	};
> > +};
> > +
> > +&pwm2 {
> > +	#pwm-cells = <3>;
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_pwm2>;
> > +	status = "okay";
> > +};
> > +
> > +&uart1 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_uart1>;
> > +	status = "okay";
> > +};
> > +
> > +&uart4 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_uart4>;
> > +	uart-has-rtscts;
> > +	status = "okay";
> > +};
> > +
> > +&usdhc2 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_usdhc2>;
> > +	cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
> > +	bus-width = <4>;
> > +	status = "okay";
> > +};
> > +
> > +&usdhc3 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_usdhc3>;
> > +	bus-width = <8>;
> > +	non-removable;
> > +	status = "okay";
> > +};
> > +
> > +&weim {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_weim_nor &pinctrl_weim_cs0>;
> > +	#address-cells = <2>;
> > +	#size-cells = <1>;
> 
> These two properties can be saved from board dts since commit
> 1be81ea58607 ("ARM: dts: imx6: Add imx-weim parameters to dtsi's").

Ok, I will remove them.

> 
> Shawn
> 
> > +	ranges = <0 0 0x08000000 0x08000000>;
> > +	status = "okay";
> > +
> > +	nor@0,0 {
> > +		compatible = "cfi-flash";
> > +		reg = <0 0 0x02000000>;
> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +		bank-width = <2>;
> > +		use-advanced-sector-protection;
> > +		fsl,weim-cs-timing = <0x00620081 0x00000001
> > 0x1c022000
> > +				0x0000c000 0x1404a38e 0x00000000>;
> > +	};
> > +};
> > -- 
> > 2.1.4
> > 


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd-ynQEQJNshbs@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

* [PATCH v2 2/2] ARM: dts: imx6q: Add mccmon6 board support
From: Lukasz Majewski @ 2017-01-03  6:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170103020650.GM20956@dragon>

Hi Shawn,

Thank you for your comments.

> On Tue, Jan 03, 2017 at 12:43:38AM +0100, Lukasz Majewski wrote:
> > From: Lukasz Majewski <l.majewski@majess.pl>
> > 
> > This patch provides support for Liebherr's Monitor 6 board
> > (abverrated as mccmon6) to Linux kernel.
> > 
> > Signed-off-by: Lukasz Majewski <lukma@denx.de>
> > ---
> > Changes for v2:
> > - Reorganize the dts file according to Valdimir Zapolskiy's comments
> > 
> > ---
> > MCCMON6 board support depends on following patches:
> > 
> > 1. "video: backlight: pwm_bl: Initialize fb_bl_on[x] and use_count
> > during pwm_backlight_probe()"
> > http://patchwork.ozlabs.org/patch/708844/
> > 
> > 2. "pwm: imx: Provide atomic operation for IMX PWM driver"
> > 	http://patchwork.ozlabs.org/patch/708847/ -
> > http://patchwork.ozlabs.org/patch/708843/ ---
> >  arch/arm/boot/dts/Makefile          |   1 +
> >  arch/arm/boot/dts/imx6q-mccmon6.dts | 477
> > ++++++++++++++++++++++++++++++++++++ 2 files changed, 478
> > insertions(+) create mode 100644 arch/arm/boot/dts/imx6q-mccmon6.dts
> > 
> > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > index c558ba7..0aa8e89 100644
> > --- a/arch/arm/boot/dts/Makefile
> > +++ b/arch/arm/boot/dts/Makefile
> > @@ -383,6 +383,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
> >  	imx6q-hummingboard.dtb \
> >  	imx6q-icore-rqs.dtb \
> >  	imx6q-marsboard.dtb \
> > +	imx6q-mccmon6.dtb \
> >  	imx6q-nitrogen6x.dtb \
> >  	imx6q-nitrogen6_max.dtb \
> >  	imx6q-novena.dtb \
> > diff --git a/arch/arm/boot/dts/imx6q-mccmon6.dts
> > b/arch/arm/boot/dts/imx6q-mccmon6.dts new file mode 100644
> > index 0000000..7128dc2
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/imx6q-mccmon6.dts
> > @@ -0,0 +1,477 @@
> > +/*
> > + * Copyright 2016-2017
> > + * Lukasz Majewski, DENX Software Engineering, lukma at denx.de
> > + *
> > + * This program is free software; you can redistribute it and/or
> > modify
> > + * it under the terms of the GNU General Public License version 2
> > as
> > + * published by the Free Software Foundation.
> > + *
> > + */
> 
> You might want to GPL/X11 dual licence for non-Linux device tree
> users. There are a plenty of examples in arch/arm/boot/dts.  But note
> the following correction.
> 
> https://patchwork.kernel.org/patch/9475057/

For this board GPLv2 is enough. Is the above description correct or do
I need to add something?

> 
> > +
> > +/dts-v1/;
> > +
> > +#include "imx6q.dtsi"
> > +
> > +#include <dt-bindings/gpio/gpio.h>
> > +#include <dt-bindings/pwm/pwm.h>
> > +
> > +/ {
> > +	model = "Liebherr (LWN) monitor6 i.MX6 Quad Board";
> > +	compatible = "lwn,mccmon6", "fsl,imx6q";
> > +
> > +	memory {
> > +		reg = <0x10000000 0x80000000>;
> > +	};
> > +
> > +	backlight_lvds: backlight {
> > +		compatible = "pwm-backlight";
> > +		pinctrl-names = "default";
> > +		pinctrl-0 = <&pinctrl_backlight>;
> > +		pwms = <&pwm2 0 5000000 PWM_POLARITY_INVERTED>;
> > +		brightness-levels = <  0   1   2   3   4   5   6
> > 7   8   9
> > +				      10  11  12  13  14  15  16
> > 17  18  19
> > +				      20  21  22  23  24  25  26
> > 27  28  29
> > +				      30  31  32  33  34  35  36
> > 37  38  39
> > +				      40  41  42  43  44  45  46
> > 47  48  49
> > +				      50  51  52  53  54  55  56
> > 57  58  59
> > +				      60  61  62  63  64  65  66
> > 67  68  69
> > +				      70  71  72  73  74  75  76
> > 77  78  79
> > +				      80  81  82  83  84  85  86
> > 87  88  89
> > +				      90  91  92  93  94  95  96
> > 97  98  99
> > +				     100 101 102 103 104 105 106
> > 107 108 109
> > +				     110 111 112 113 114 115 116
> > 117 118 119
> > +				     120 121 122 123 124 125 126
> > 127 128 129
> > +				     130 131 132 133 134 135 136
> > 137 138 139
> > +				     140 141 142 143 144 145 146
> > 147 148 149
> > +				     150 151 152 153 154 155 156
> > 157 158 159
> > +				     160 161 162 163 164 165 166
> > 167 168 169
> > +				     170 171 172 173 174 175 176
> > 177 178 179
> > +				     180 181 182 183 184 185 186
> > 187 188 189
> > +				     190 191 192 193 194 195 196
> > 197 198 199
> > +				     200 201 202 203 204 205 206
> > 207 208 209
> > +				     210 211 212 213 214 215 216
> > 217 218 219
> > +				     220 221 222 223 224 225 226
> > 227 228 229
> > +				     230 231 232 233 234 235 236
> > 237 238 239
> > +				     240 241 242 243 244 245 246
> > 247 248 249
> > +				     250 251 252 253 254 255>;
> > +		default-brightness-level = <50>;
> > +		enable-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
> > +	};
> > +
> > +	reg_lvds: regulator-lvds {
> > +		compatible = "regulator-fixed";
> > +		regulator-name = "lvds_ppen";
> > +		regulator-min-microvolt = <3300000>;
> > +		regulator-max-microvolt = <3300000>;
> > +		regulator-boot-on;
> > +		pinctrl-names = "default";
> > +		pinctrl-0 = <&pinctrl_reg_lvds>;
> > +		gpio = <&gpio1 19 GPIO_ACTIVE_HIGH>;
> > +		enable-active-high;
> > +	};
> > +
> > +	panel-lvds0 {
> > +		compatible = "innolux,g121x1-l03";
> > +		backlight = <&backlight_lvds>;
> > +		power-supply = <&reg_lvds>;
> > +
> > +		port {
> > +			panel_in_lvds0: endpoint {
> > +				remote-endpoint = <&lvds0_out>;
> > +			};
> > +		};
> > +	};
> > +};
> > +
> > +&iomuxc {
> 
> Considering the data amount of this node, we generally put it at the
> bottom of the file to improve the readability of the rest.

But then it will not be alphabetically ordered :-).

I can put it on the end - no problem.

> 
> > +	pinctrl-names = "default";
> > +
> > +	imx6q-mccmon6 {
> 
> This container node can now be dropped completely to save one level of
> indentation.

Ok, I will remove imx6q-mccmon6 container node completely.

> 
> > +		pinctrl_backlight: dispgrp {
> > +			fsl,pins = <
> > +				/* BLEN_OUT */
> > +				MX6QDL_PAD_GPIO_2__GPIO1_IO02
> > 0x1b0b0
> > +			>;
> > +		};
> > +
> > +		pinctrl_ecspi3: ecspi3grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO	0x100b1
> > +
> > MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI	0x100b1
> > +
> > MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK	0x100b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_ecspi3_cs: ecspi3cs {
> 
> ecspi3csgrp, if we follow the naming scheme used in other nodes.
> 
> > +			fsl,pins = <
> > +				MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24
> > 0x80000000
> > +			>;
> > +		};
> > +
> > +		pinctrl_ecspi3_flwp: ecspi3flwp {
> 
> Ditto
> 
> > +			fsl,pins = <
> > +				MX6QDL_PAD_DISP0_DAT6__GPIO4_IO27
> > 0x80000000
> > +			>;
> > +		};
> > +
> > +		pinctrl_enet: enetgrp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_ENET_MDIO__ENET_MDIO		0x1b0b0
> > +
> > MX6QDL_PAD_ENET_MDC__ENET_MDC		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_TXC__RGMII_TXC		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_TD0__RGMII_TD0		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_TD1__RGMII_TD1		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_TD2__RGMII_TD2		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_TD3__RGMII_TD3		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	0x1b0b0
> > +
> > MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK	0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_RXC__RGMII_RXC		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_RD0__RGMII_RD0		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_RD1__RGMII_RD1		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_RD2__RGMII_RD2		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_RD3__RGMII_RD3		0x1b0b0
> > +
> > MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	0x1b0b0
> > +				MX6QDL_PAD_GPIO_16__ENET_REF_CLK
> > 0x4001b0a8
> > +
> > MX6QDL_PAD_GPIO_6__ENET_IRQ		0x000b1
> > +
> > MX6QDL_PAD_ENET_RXD0__GPIO1_IO27        0x1b0b0
> > +			>;
> > +		};
> > +
> > +		pinctrl_i2c1: i2c1grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_CSI0_DAT9__I2C1_SCL	0x4001b8b1
> > +
> > MX6QDL_PAD_CSI0_DAT8__I2C1_SDA	0x4001b8b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_i2c2: i2c2grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_KEY_COL3__I2C2_SCL	0x4001b8b1
> > +
> > MX6QDL_PAD_KEY_ROW3__I2C2_SDA	0x4001b8b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_pwm2: pwm2grp {
> > +			fsl,pins = <
> > +				MX6QDL_PAD_GPIO_1__PWM2_OUT
> > 0x1b0b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_reg_lvds: req_lvds_grp {
> 
> reglvdsgrp
> 
> > +			fsl,pins = <
> > +				/* LVDS_PPEN_OUT */
> > +
> > MX6QDL_PAD_SD1_DAT2__GPIO1_IO19         0x1b0b0
> > +			>;
> > +		};
> > +
> > +		pinctrl_uart1: uart1grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA	0x1b0b1
> > +
> > MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA	0x1b0b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_uart4: uart4grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_KEY_COL0__UART4_TX_DATA	0x1b0b1
> > +
> > MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA	0x1b0b1
> > +
> > MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B	0x1b0b1
> > +
> > MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B	0x1b0b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_usdhc2: usdhc2grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_SD2_CMD__SD2_CMD		0x17059
> > +
> > MX6QDL_PAD_SD2_CLK__SD2_CLK		0x10059
> > +
> > MX6QDL_PAD_SD2_DAT0__SD2_DATA0		0x17059
> > +
> > MX6QDL_PAD_SD2_DAT1__SD2_DATA1		0x17059
> > +
> > MX6QDL_PAD_SD2_DAT2__SD2_DATA2		0x17059
> > +
> > MX6QDL_PAD_SD2_DAT3__SD2_DATA3		0x17059
> > +
> > MX6QDL_PAD_GPIO_4__GPIO1_IO04           0x1b0b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_usdhc3: usdhc3grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_SD3_CMD__SD3_CMD		0x17059
> > +
> > MX6QDL_PAD_SD3_CLK__SD3_CLK		0x10059
> > +
> > MX6QDL_PAD_SD3_DAT0__SD3_DATA0		0x17059
> > +
> > MX6QDL_PAD_SD3_DAT1__SD3_DATA1		0x17059
> > +
> > MX6QDL_PAD_SD3_DAT2__SD3_DATA2		0x17059
> > +
> > MX6QDL_PAD_SD3_DAT3__SD3_DATA3		0x17059
> > +
> > MX6QDL_PAD_SD3_DAT4__SD3_DATA4		0x17059
> > +
> > MX6QDL_PAD_SD3_DAT5__SD3_DATA5		0x17059
> > +
> > MX6QDL_PAD_SD3_DAT6__SD3_DATA6		0x17059
> > +
> > MX6QDL_PAD_SD3_DAT7__SD3_DATA7		0x17059
> > +
> > MX6QDL_PAD_SD3_RST__SD3_RESET		0x17059
> > +			>;
> > +		};
> > +
> > +		pinctrl_weim_cs0: weimcs0grp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_EIM_CS0__EIM_CS0_B		0xb0b1
> > +			>;
> > +		};
> > +
> > +		pinctrl_weim_nor: weimnorgrp {
> > +			fsl,pins = <
> > +
> > MX6QDL_PAD_EIM_OE__EIM_OE_B		0xb0b1
> > +
> > MX6QDL_PAD_EIM_RW__EIM_RW		0xb0b1
> > +
> > MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B	0xb060
> > +
> > MX6QDL_PAD_EIM_D16__EIM_DATA16		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D17__EIM_DATA17		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D18__EIM_DATA18		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D19__EIM_DATA19		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D20__EIM_DATA20		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D21__EIM_DATA21		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D22__EIM_DATA22		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D23__EIM_DATA23		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D24__EIM_DATA24		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D25__EIM_DATA25		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D26__EIM_DATA26		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D27__EIM_DATA27		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D28__EIM_DATA28		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D29__EIM_DATA29		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D30__EIM_DATA30		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_D31__EIM_DATA31		0x1b0b0
> > +
> > MX6QDL_PAD_EIM_A23__EIM_ADDR23		0xb0b1
> > +
> > MX6QDL_PAD_EIM_A22__EIM_ADDR22		0xb0b1
> > +
> > MX6QDL_PAD_EIM_A21__EIM_ADDR21		0xb0b1
> > +
> > MX6QDL_PAD_EIM_A20__EIM_ADDR20		0xb0b1
> > +
> > MX6QDL_PAD_EIM_A19__EIM_ADDR19		0xb0b1
> > +
> > MX6QDL_PAD_EIM_A18__EIM_ADDR18		0xb0b1
> > +
> > MX6QDL_PAD_EIM_A17__EIM_ADDR17		0xb0b1
> > +
> > MX6QDL_PAD_EIM_A16__EIM_ADDR16		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA15__EIM_AD15		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA14__EIM_AD14		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA13__EIM_AD13		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA12__EIM_AD12		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA11__EIM_AD11		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA10__EIM_AD10		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA9__EIM_AD09		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA8__EIM_AD08		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA7__EIM_AD07		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA6__EIM_AD06		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA5__EIM_AD05		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA4__EIM_AD04		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA3__EIM_AD03		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA2__EIM_AD02		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA1__EIM_AD01		0xb0b1
> > +
> > MX6QDL_PAD_EIM_DA0__EIM_AD00		0xb0b1
> > +			>;
> > +		};
> > +	};
> > +};
> > +
> > +&ecspi3 {
> > +	cs-gpios = <&gpio4 24 0>;
> 
> GPIO_ACTIVE_HIGH?

No, on our HW it is GPIO_ACTIVE_LOW

> 
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_ecspi3 &pinctrl_ecspi3_cs
> > &pinctrl_ecspi3_flwp>;
> > +	status = "okay";
> > +
> > +	flash: s25sl032p at 0 {
> 
> Node name should be as generic as possible, while label name can be
> specific.  That said, 's25sl032p: flash at 0' should be better.

OK.

> 
> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +		compatible = "spansion,s25sl032p", "jedec,spi-nor";
> 
> "spansion,s25sl032p" doesn't seem to be documented.  Can it be
> dropped?

This memory is jedec compatible and uses "jedec,spi-nor", so
"spansion,s25sl032p" can be dropped

> 
> > +		spi-max-frequency = <40000000>;
> > +		reg = <0>;
> > +	};
> > +};
> > +
> > +&fec {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_enet>;
> > +	phy-mode = "rgmii";
> > +	phy-reset-gpios = <&gpio1 27 0>;
> 
> GPIO_ACTIVE_xxx?  But you probably need GPIO_ACTIVE_LOW.

Yes.

> 
> > +	interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
> > +			      <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
> > +	status = "okay";
> > +};
> > +
> > +&i2c1 {
> > +	clock-frequency = <100000>;
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_i2c1>;
> > +	status = "okay";
> > +};
> > +
> > +&i2c2 {
> > +	clock-frequency = <100000>;
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_i2c2>;
> > +	status = "okay";
> > +
> > +	pmic: pfuze100 at 08 {
> 
> pfuze100: pmic at 08
> 
> > +		compatible = "fsl,pfuze100";
> > +		reg = <0x08>;
> > +
> > +		regulators {
> > +			sw1a_reg: sw1ab {
> > +				regulator-min-microvolt = <300000>;
> > +				regulator-max-microvolt =
> > <1875000>;
> > +				regulator-boot-on;
> > +				regulator-always-on;
> > +				regulator-ramp-delay = <6250>;
> > +			};
> > +
> > +			sw1c_reg: sw1c {
> > +				regulator-min-microvolt = <300000>;
> > +				regulator-max-microvolt =
> > <1875000>;
> > +				regulator-boot-on;
> > +				regulator-always-on;
> > +				regulator-ramp-delay = <6250>;
> > +			};
> > +
> > +			sw2_reg: sw2 {
> > +				regulator-min-microvolt = <800000>;
> > +				regulator-max-microvolt =
> > <3950000>;
> > +				regulator-boot-on;
> > +				regulator-always-on;
> > +			};
> > +
> > +			sw3a_reg: sw3a {
> > +				regulator-min-microvolt = <400000>;
> > +				regulator-max-microvolt =
> > <1975000>;
> > +				regulator-boot-on;
> > +				regulator-always-on;
> > +			};
> > +
> > +			sw3b_reg: sw3b {
> > +				regulator-min-microvolt = <400000>;
> > +				regulator-max-microvolt =
> > <1975000>;
> > +				regulator-boot-on;
> > +				regulator-always-on;
> > +			};
> > +
> > +			sw4_reg: sw4 {
> > +				regulator-min-microvolt = <800000>;
> > +				regulator-max-microvolt =
> > <3300000>;
> > +			};
> > +
> > +			swbst_reg: swbst {
> > +				regulator-min-microvolt =
> > <5000000>;
> > +				regulator-max-microvolt =
> > <5150000>;
> > +			};
> > +
> > +			snvs_reg: vsnvs {
> > +				regulator-min-microvolt =
> > <1000000>;
> > +				regulator-max-microvolt =
> > <3000000>;
> > +				regulator-boot-on;
> > +				regulator-always-on;
> > +			};
> > +
> > +			vref_reg: vrefddr {
> > +				regulator-boot-on;
> > +				regulator-always-on;
> > +			};
> > +
> > +			vgen1_reg: vgen1 {
> > +				regulator-min-microvolt = <800000>;
> > +				regulator-max-microvolt =
> > <1550000>;
> > +			};
> > +
> > +			vgen2_reg: vgen2 {
> > +				regulator-min-microvolt = <800000>;
> > +				regulator-max-microvolt =
> > <1550000>;
> > +			};
> > +
> > +			vgen3_reg: vgen3 {
> > +				regulator-min-microvolt =
> > <1800000>;
> > +				regulator-max-microvolt =
> > <3300000>;
> > +			};
> > +
> > +			vgen4_reg: vgen4 {
> > +				regulator-min-microvolt =
> > <1800000>;
> > +				regulator-max-microvolt =
> > <3300000>;
> > +				regulator-always-on;
> > +			};
> > +
> > +			vgen5_reg: vgen5 {
> > +				regulator-min-microvolt =
> > <1800000>;
> > +				regulator-max-microvolt =
> > <3300000>;
> > +				regulator-always-on;
> > +			};
> > +
> > +			vgen6_reg: vgen6 {
> > +				regulator-min-microvolt =
> > <1800000>;
> > +				regulator-max-microvolt =
> > <3300000>;
> > +				regulator-always-on;
> > +			};
> > +		};
> > +	};
> > +};
> > +
> > +&ldb {
> > +	status = "okay";
> > +
> > +	lvds0: lvds-channel at 0 {
> > +		fsl,data-mapping = "spwg";
> > +		fsl,data-width = <24>;
> > +		status = "okay";
> > +
> > +		port at 4 {
> > +			reg = <4>;
> > +
> > +			lvds0_out: endpoint {
> > +				remote-endpoint =
> > <&panel_in_lvds0>;
> > +			};
> > +		};
> > +	};
> > +};
> > +
> > +&pwm2 {
> > +	#pwm-cells = <3>;
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_pwm2>;
> > +	status = "okay";
> > +};
> > +
> > +&uart1 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_uart1>;
> > +	status = "okay";
> > +};
> > +
> > +&uart4 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_uart4>;
> > +	uart-has-rtscts;
> > +	status = "okay";
> > +};
> > +
> > +&usdhc2 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_usdhc2>;
> > +	cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
> > +	bus-width = <4>;
> > +	status = "okay";
> > +};
> > +
> > +&usdhc3 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_usdhc3>;
> > +	bus-width = <8>;
> > +	non-removable;
> > +	status = "okay";
> > +};
> > +
> > +&weim {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pinctrl_weim_nor &pinctrl_weim_cs0>;
> > +	#address-cells = <2>;
> > +	#size-cells = <1>;
> 
> These two properties can be saved from board dts since commit
> 1be81ea58607 ("ARM: dts: imx6: Add imx-weim parameters to dtsi's").

Ok, I will remove them.

> 
> Shawn
> 
> > +	ranges = <0 0 0x08000000 0x08000000>;
> > +	status = "okay";
> > +
> > +	nor at 0,0 {
> > +		compatible = "cfi-flash";
> > +		reg = <0 0 0x02000000>;
> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +		bank-width = <2>;
> > +		use-advanced-sector-protection;
> > +		fsl,weim-cs-timing = <0x00620081 0x00000001
> > 0x1c022000
> > +				0x0000c000 0x1404a38e 0x00000000>;
> > +	};
> > +};
> > -- 
> > 2.1.4
> > 


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de

^ permalink raw reply

* Re: [RFC PATCH] virtio_net: XDP support for adjust_head
From: Jason Wang @ 2017-01-03  6:01 UTC (permalink / raw)
  To: John Fastabend, mst; +Cc: john.r.fastabend, netdev, alexei.starovoitov, daniel
In-Reply-To: <20170102194413.9089.39078.stgit@john-Precision-Tower-5810>



On 2017年01月03日 03:44, John Fastabend wrote:
> Add support for XDP adjust head by allocating a 256B header region
> that XDP programs can grow into. This is only enabled when a XDP
> program is loaded.
>
> In order to ensure that we do not have to unwind queue headroom push
> queue setup below bpf_prog_add. It reads better to do a prog ref
> unwind vs another queue setup call.
>
> : There is a problem with this patch as is. When xdp prog is loaded
>    the old buffers without the 256B headers need to be flushed so that
>    the bpf prog has the necessary headroom. This patch does this by
>    calling the virtqueue_detach_unused_buf() and followed by the
>    virtnet_set_queues() call to reinitialize the buffers. However I
>    don't believe this is safe per comment in virtio_ring this API
>    is not valid on an active queue and the only thing we have done
>    here is napi_disable/napi_enable wrappers which doesn't do anything
>    to the emulation layer.
>
>    So the RFC is really to find the best solution to this problem.
>    A couple things come to mind, (a) always allocate the necessary
>    headroom but this is a bit of a waste (b) add some bit somewhere
>    to check if the buffer has headroom but this would mean XDP programs
>    would be broke for a cycle through the ring, (c) figure out how
>    to deactivate a queue, free the buffers and finally reallocate.
>    I think (c) is the best choice for now but I'm not seeing the
>    API to do this so virtio/qemu experts anyone know off-hand
>    how to make this work? I started looking into the PCI callbacks
>    reset() and virtio_device_ready() or possibly hitting the right
>    set of bits with vp_set_status() but my first attempt just hung
>    the device.

Hi John:

AFAIK, disabling a specific queue was supported only by virtio 1.0 
through queue_enable field in pci common cfg. But unfortunately, qemu 
does not emulate this at all and legacy device does not even support 
this. So the safe way is probably reset the device and redo the 
initialization here.

>
> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> ---
>   drivers/net/virtio_net.c |  106 +++++++++++++++++++++++++++++++++++-----------
>   1 file changed, 80 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 5deeda6..fcc5bd7 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -159,6 +159,9 @@ struct virtnet_info {
>   	/* Ethtool settings */
>   	u8 duplex;
>   	u32 speed;
> +
> +	/* Headroom allocated in RX Queue */
> +	unsigned int headroom;
>   };
>   
>   struct padded_vnet_hdr {
> @@ -355,6 +358,7 @@ static void virtnet_xdp_xmit(struct virtnet_info *vi,
>   	}
>   
>   	if (vi->mergeable_rx_bufs) {
> +		xdp->data -= sizeof(struct virtio_net_hdr_mrg_rxbuf);
>   		/* Zero header and leave csum up to XDP layers */
>   		hdr = xdp->data;
>   		memset(hdr, 0, vi->hdr_len);
> @@ -371,7 +375,7 @@ static void virtnet_xdp_xmit(struct virtnet_info *vi,
>   		num_sg = 2;
>   		sg_init_table(sq->sg, 2);
>   		sg_set_buf(sq->sg, hdr, vi->hdr_len);
> -		skb_to_sgvec(skb, sq->sg + 1, 0, skb->len);
> +		skb_to_sgvec(skb, sq->sg + 1, vi->headroom, xdp->data_end - xdp->data);

vi->headroom look suspicious, should it be xdp->data - xdp->data_hard_start?

>   	}
>   	err = virtqueue_add_outbuf(sq->vq, sq->sg, num_sg,
>   				   data, GFP_ATOMIC);
> @@ -393,34 +397,39 @@ static u32 do_xdp_prog(struct virtnet_info *vi,
>   		       struct bpf_prog *xdp_prog,
>   		       void *data, int len)
>   {
> -	int hdr_padded_len;
>   	struct xdp_buff xdp;
> -	void *buf;
>   	unsigned int qp;
>   	u32 act;
>   
> +
>   	if (vi->mergeable_rx_bufs) {
> -		hdr_padded_len = sizeof(struct virtio_net_hdr_mrg_rxbuf);
> -		xdp.data = data + hdr_padded_len;
> +		int desc_room = sizeof(struct virtio_net_hdr_mrg_rxbuf);
> +
> +		/* Allow consuming headroom but reserve enough space to push
> +		 * the descriptor on if we get an XDP_TX return code.
> +		 */
> +		xdp.data_hard_start = data - vi->headroom + desc_room;
> +		xdp.data = data + desc_room;
>   		xdp.data_end = xdp.data + (len - vi->hdr_len);
> -		buf = data;
>   	} else { /* small buffers */
>   		struct sk_buff *skb = data;
>   
> -		xdp.data = skb->data;
> +		xdp.data_hard_start = skb->data;
> +		xdp.data = skb->data + vi->headroom;
>   		xdp.data_end = xdp.data + len;
> -		buf = skb->data;
>   	}
>   
>   	act = bpf_prog_run_xdp(xdp_prog, &xdp);
>   	switch (act) {
>   	case XDP_PASS:
> +		if (!vi->mergeable_rx_bufs)
> +			__skb_pull((struct sk_buff *) data,
> +				   xdp.data - xdp.data_hard_start);

Instead of doing things here and virtnet_xdp_xmit(). How about always 
making skb->data point to the buffer head like:

1) reserve headroom in add_recvbuf_small()
2) skb_push(xdp->data - xdp_data_hard_start, skb) if we detect xdp->data 
was modified afer bpf_prog_run_xdp()

Then there's no special code in either XDP_PASS or XDP_TX?

>   		return XDP_PASS;
>   	case XDP_TX:
>   		qp = vi->curr_queue_pairs -
>   			vi->xdp_queue_pairs +
>   			smp_processor_id();

[...]

> +#define VIRTIO_XDP_HEADROOM 256
> +
>   static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
>   {
>   	unsigned long int max_sz = PAGE_SIZE - sizeof(struct padded_vnet_hdr);
>   	struct virtnet_info *vi = netdev_priv(dev);
>   	struct bpf_prog *old_prog;
>   	u16 xdp_qp = 0, curr_qp;
> +	unsigned int old_hr;
>   	int i, err;
>   
>   	if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO4) ||
> @@ -1736,19 +1751,58 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
>   		return -ENOMEM;
>   	}
>   
> +	old_hr = vi->headroom;
> +	if (prog) {
> +		prog = bpf_prog_add(prog, vi->max_queue_pairs - 1);
> +		if (IS_ERR(prog))
> +			return PTR_ERR(prog);
> +		vi->headroom = VIRTIO_XDP_HEADROOM;
> +	} else {
> +		vi->headroom = 0;
> +	}
> +
> +	/* Changing the headroom in buffers is a disruptive operation because
> +	 * existing buffers must be flushed and reallocated. This will happen
> +	 * when a xdp program is initially added or xdp is disabled by removing
> +	 * the xdp program.
> +	 */

We probably need reset the device here, but maybe Michale has more 
ideas. And if we do this, another interesting thing to do is to disable 
EWMA and always use a single page for each packet, this could almost 
eliminate linearizing.

Thanks

^ permalink raw reply

* [PATCHv2 net-next 3/3] sctp: remove asoc ssnmap and ssnmap.c
From: Xin Long @ 2017-01-03  5:59 UTC (permalink / raw)
  To: network dev, linux-sctp
  Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
In-Reply-To: <cover.1483422833.git.lucien.xin@gmail.com>

Since asoc stream arrays has replaced ssnmap, ssnmap is not used any
more, this patch is to remove asoc ssnmap and ssnmap.c.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/net/sctp/sctp.h    |   1 -
 include/net/sctp/structs.h |  33 ------------
 net/sctp/Makefile          |   3 +-
 net/sctp/objcnt.c          |   2 -
 net/sctp/ssnmap.c          | 125 ---------------------------------------------
 5 files changed, 1 insertion(+), 163 deletions(-)
 delete mode 100644 net/sctp/ssnmap.c

diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index d8833a8..598d938 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -283,7 +283,6 @@ extern atomic_t sctp_dbg_objcnt_chunk;
 extern atomic_t sctp_dbg_objcnt_bind_addr;
 extern atomic_t sctp_dbg_objcnt_bind_bucket;
 extern atomic_t sctp_dbg_objcnt_addr;
-extern atomic_t sctp_dbg_objcnt_ssnmap;
 extern atomic_t sctp_dbg_objcnt_datamsg;
 extern atomic_t sctp_dbg_objcnt_keys;
 
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index f81c321..9075d61 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -82,7 +82,6 @@ struct sctp_outq;
 struct sctp_bind_addr;
 struct sctp_ulpq;
 struct sctp_ep_common;
-struct sctp_ssnmap;
 struct crypto_shash;
 
 
@@ -377,35 +376,6 @@ typedef struct sctp_sender_hb_info {
 	__u64 hb_nonce;
 } __packed sctp_sender_hb_info_t;
 
-/*
- *  RFC 2960 1.3.2 Sequenced Delivery within Streams
- *
- *  The term "stream" is used in SCTP to refer to a sequence of user
- *  messages that are to be delivered to the upper-layer protocol in
- *  order with respect to other messages within the same stream.  This is
- *  in contrast to its usage in TCP, where it refers to a sequence of
- *  bytes (in this document a byte is assumed to be eight bits).
- *  ...
- *
- *  This is the structure we use to track both our outbound and inbound
- *  SSN, or Stream Sequence Numbers.
- */
-
-struct sctp_stream {
-	__u16 *ssn;
-	unsigned int len;
-};
-
-struct sctp_ssnmap {
-	struct sctp_stream in;
-	struct sctp_stream out;
-};
-
-struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out,
-				    gfp_t gfp);
-void sctp_ssnmap_free(struct sctp_ssnmap *map);
-void sctp_ssnmap_clear(struct sctp_ssnmap *map);
-
 /* What is the current SSN number for this stream? */
 #define sctp_ssn_peek(asoc, type, sid) \
 	((asoc)->stream##type[sid].ssn)
@@ -1751,9 +1721,6 @@ struct sctp_association {
 	/* Default receive parameters */
 	__u32 default_rcv_context;
 
-	/* This tracks outbound ssn for a given stream.	 */
-	struct sctp_ssnmap *ssnmap;
-
 	/* All outbound chunks go through this structure.  */
 	struct sctp_outq outqueue;
 
diff --git a/net/sctp/Makefile b/net/sctp/Makefile
index 6c4f749..48bfc74 100644
--- a/net/sctp/Makefile
+++ b/net/sctp/Makefile
@@ -11,8 +11,7 @@ sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \
 	  transport.o chunk.o sm_make_chunk.o ulpevent.o \
 	  inqueue.o outqueue.o ulpqueue.o \
 	  tsnmap.o bind_addr.o socket.o primitive.o \
-	  output.o input.o debug.o ssnmap.o auth.o \
-	  offload.o
+	  output.o input.o debug.o auth.o offload.o
 
 sctp_probe-y := probe.o
 
diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c
index 40e7fac..105ac33 100644
--- a/net/sctp/objcnt.c
+++ b/net/sctp/objcnt.c
@@ -51,7 +51,6 @@ SCTP_DBG_OBJCNT(bind_addr);
 SCTP_DBG_OBJCNT(bind_bucket);
 SCTP_DBG_OBJCNT(chunk);
 SCTP_DBG_OBJCNT(addr);
-SCTP_DBG_OBJCNT(ssnmap);
 SCTP_DBG_OBJCNT(datamsg);
 SCTP_DBG_OBJCNT(keys);
 
@@ -67,7 +66,6 @@ static sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = {
 	SCTP_DBG_OBJCNT_ENTRY(bind_addr),
 	SCTP_DBG_OBJCNT_ENTRY(bind_bucket),
 	SCTP_DBG_OBJCNT_ENTRY(addr),
-	SCTP_DBG_OBJCNT_ENTRY(ssnmap),
 	SCTP_DBG_OBJCNT_ENTRY(datamsg),
 	SCTP_DBG_OBJCNT_ENTRY(keys),
 };
diff --git a/net/sctp/ssnmap.c b/net/sctp/ssnmap.c
deleted file mode 100644
index b9c8521..0000000
--- a/net/sctp/ssnmap.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/* SCTP kernel implementation
- * Copyright (c) 2003 International Business Machines, Corp.
- *
- * This file is part of the SCTP kernel implementation
- *
- * These functions manipulate sctp SSN tracker.
- *
- * This SCTP implementation 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, or (at your option)
- * any later version.
- *
- * This SCTP implementation 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * Please send any bug reports or fixes you make to the
- * email address(es):
- *    lksctp developers <linux-sctp@vger.kernel.org>
- *
- * Written or modified by:
- *    Jon Grimm             <jgrimm@us.ibm.com>
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <net/sctp/sctp.h>
-#include <net/sctp/sm.h>
-
-static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
-					    __u16 out);
-
-/* Storage size needed for map includes 2 headers and then the
- * specific needs of in or out streams.
- */
-static inline size_t sctp_ssnmap_size(__u16 in, __u16 out)
-{
-	return sizeof(struct sctp_ssnmap) + (in + out) * sizeof(__u16);
-}
-
-
-/* Create a new sctp_ssnmap.
- * Allocate room to store at least 'len' contiguous TSNs.
- */
-struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out,
-				    gfp_t gfp)
-{
-	struct sctp_ssnmap *retval;
-	int size;
-
-	size = sctp_ssnmap_size(in, out);
-	if (size <= KMALLOC_MAX_SIZE)
-		retval = kmalloc(size, gfp);
-	else
-		retval = (struct sctp_ssnmap *)
-			  __get_free_pages(gfp, get_order(size));
-	if (!retval)
-		goto fail;
-
-	if (!sctp_ssnmap_init(retval, in, out))
-		goto fail_map;
-
-	SCTP_DBG_OBJCNT_INC(ssnmap);
-
-	return retval;
-
-fail_map:
-	if (size <= KMALLOC_MAX_SIZE)
-		kfree(retval);
-	else
-		free_pages((unsigned long)retval, get_order(size));
-fail:
-	return NULL;
-}
-
-
-/* Initialize a block of memory as a ssnmap.  */
-static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
-					    __u16 out)
-{
-	memset(map, 0x00, sctp_ssnmap_size(in, out));
-
-	/* Start 'in' stream just after the map header. */
-	map->in.ssn = (__u16 *)&map[1];
-	map->in.len = in;
-
-	/* Start 'out' stream just after 'in'. */
-	map->out.ssn = &map->in.ssn[in];
-	map->out.len = out;
-
-	return map;
-}
-
-/* Clear out the ssnmap streams.  */
-void sctp_ssnmap_clear(struct sctp_ssnmap *map)
-{
-	size_t size;
-
-	size = (map->in.len + map->out.len) * sizeof(__u16);
-	memset(map->in.ssn, 0x00, size);
-}
-
-/* Dispose of a ssnmap.  */
-void sctp_ssnmap_free(struct sctp_ssnmap *map)
-{
-	int size;
-
-	if (unlikely(!map))
-		return;
-
-	size = sctp_ssnmap_size(map->in.len, map->out.len);
-	if (size <= KMALLOC_MAX_SIZE)
-		kfree(map);
-	else
-		free_pages((unsigned long)map, get_order(size));
-
-	SCTP_DBG_OBJCNT_DEC(ssnmap);
-}
-- 
2.1.0

^ permalink raw reply related

* [PATCHv2 net-next 2/3] sctp: replace ssnmap with asoc stream arrays
From: Xin Long @ 2017-01-03  5:59 UTC (permalink / raw)
  To: network dev, linux-sctp
  Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
In-Reply-To: <cover.1483422833.git.lucien.xin@gmail.com>

Stream arrays are used to save per stream information, which includes
ssn for each stream already.

This patch is to replace ssnmap with asoc stream arrays.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/net/sctp/structs.h | 19 ++++++-------------
 net/sctp/associola.c       | 10 ----------
 net/sctp/sm_make_chunk.c   | 11 ++---------
 net/sctp/sm_statefuns.c    |  3 +--
 net/sctp/ulpqueue.c        | 33 +++++++++++----------------------
 5 files changed, 20 insertions(+), 56 deletions(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 549f17d..f81c321 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -407,23 +407,16 @@ void sctp_ssnmap_free(struct sctp_ssnmap *map);
 void sctp_ssnmap_clear(struct sctp_ssnmap *map);
 
 /* What is the current SSN number for this stream? */
-static inline __u16 sctp_ssn_peek(struct sctp_stream *stream, __u16 id)
-{
-	return stream->ssn[id];
-}
+#define sctp_ssn_peek(asoc, type, sid) \
+	((asoc)->stream##type[sid].ssn)
 
 /* Return the next SSN number for this stream.	*/
-static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id)
-{
-	return stream->ssn[id]++;
-}
+#define sctp_ssn_next(asoc, type, sid) \
+	((asoc)->stream##type[sid].ssn++)
 
 /* Skip over this ssn and all below. */
-static inline void sctp_ssn_skip(struct sctp_stream *stream, __u16 id, 
-				 __u16 ssn)
-{
-	stream->ssn[id] = ssn+1;
-}
+#define sctp_ssn_skip(asoc, type, sid, ssn) \
+	((asoc)->stream##type[sid].ssn = ssn + 1)
               
 /*
  * Pointers to address related SCTP functions.
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 290ec4d..ea03270 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -358,9 +358,6 @@ void sctp_association_free(struct sctp_association *asoc)
 
 	sctp_tsnmap_free(&asoc->peer.tsn_map);
 
-	/* Free ssnmap storage. */
-	sctp_ssnmap_free(asoc->ssnmap);
-
 	/* Free stream information. */
 	kfree(asoc->streamout);
 	kfree(asoc->streamin);
@@ -1143,8 +1140,6 @@ void sctp_assoc_update(struct sctp_association *asoc,
 		/* Reinitialize SSN for both local streams
 		 * and peer's streams.
 		 */
-		sctp_ssnmap_clear(asoc->ssnmap);
-
 		for (i = 0; i < asoc->streamoutcnt; i++)
 			asoc->streamout[i].ssn = 0;
 
@@ -1174,11 +1169,6 @@ void sctp_assoc_update(struct sctp_association *asoc,
 
 		asoc->ctsn_ack_point = asoc->next_tsn - 1;
 		asoc->adv_peer_ack_point = asoc->ctsn_ack_point;
-		if (!asoc->ssnmap) {
-			/* Move the ssnmap. */
-			asoc->ssnmap = new->ssnmap;
-			new->ssnmap = NULL;
-		}
 
 		if (!asoc->streamin && !asoc->streamout) {
 			asoc->streamout = new->streamout;
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index eeadeef..78cbd1b 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1527,7 +1527,6 @@ void sctp_chunk_assign_ssn(struct sctp_chunk *chunk)
 {
 	struct sctp_datamsg *msg;
 	struct sctp_chunk *lchunk;
-	struct sctp_stream *stream;
 	__u16 ssn;
 	__u16 sid;
 
@@ -1536,7 +1535,6 @@ void sctp_chunk_assign_ssn(struct sctp_chunk *chunk)
 
 	/* All fragments will be on the same stream */
 	sid = ntohs(chunk->subh.data_hdr->stream);
-	stream = &chunk->asoc->ssnmap->out;
 
 	/* Now assign the sequence number to the entire message.
 	 * All fragments must have the same stream sequence number.
@@ -1547,9 +1545,9 @@ void sctp_chunk_assign_ssn(struct sctp_chunk *chunk)
 			ssn = 0;
 		} else {
 			if (lchunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG)
-				ssn = sctp_ssn_next(stream, sid);
+				ssn = sctp_ssn_next(chunk->asoc, out, sid);
 			else
-				ssn = sctp_ssn_peek(stream, sid);
+				ssn = sctp_ssn_peek(chunk->asoc, out, sid);
 		}
 
 		lchunk->subh.data_hdr->ssn = htons(ssn);
@@ -2447,11 +2445,6 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
 		asoc->streamoutcnt = asoc->c.sinit_num_ostreams;
 		asoc->streamincnt = asoc->c.sinit_max_instreams;
 
-		asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
-					       asoc->c.sinit_num_ostreams, gfp);
-		if (!asoc->ssnmap)
-			goto clean_up;
-
 		asoc->streamout = kcalloc(asoc->streamoutcnt,
 					  sizeof(*asoc->streamout), gfp);
 		if (!asoc->streamout)
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 3382ef2..8a130a7 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -6274,9 +6274,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
 	 * and is invalid.
 	 */
 	ssn = ntohs(data_hdr->ssn);
-	if (ordered && SSN_lt(ssn, sctp_ssn_peek(&asoc->ssnmap->in, sid))) {
+	if (ordered && SSN_lt(ssn, sctp_ssn_peek(asoc, in, sid)))
 		return SCTP_IERROR_PROTO_VIOLATION;
-	}
 
 	/* Send the data up to the user.  Note:  Schedule  the
 	 * SCTP_CMD_CHUNK_ULP cmd before the SCTP_CMD_GEN_SACK, as the SACK
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index 84d0fda..0d8bf26 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -760,11 +760,9 @@ static void sctp_ulpq_retrieve_ordered(struct sctp_ulpq *ulpq,
 	struct sk_buff_head *event_list;
 	struct sk_buff *pos, *tmp;
 	struct sctp_ulpevent *cevent;
-	struct sctp_stream *in;
 	__u16 sid, csid, cssn;
 
 	sid = event->stream;
-	in  = &ulpq->asoc->ssnmap->in;
 
 	event_list = (struct sk_buff_head *) sctp_event2skb(event)->prev;
 
@@ -782,11 +780,11 @@ static void sctp_ulpq_retrieve_ordered(struct sctp_ulpq *ulpq,
 		if (csid < sid)
 			continue;
 
-		if (cssn != sctp_ssn_peek(in, sid))
+		if (cssn != sctp_ssn_peek(ulpq->asoc, in, sid))
 			break;
 
-		/* Found it, so mark in the ssnmap. */
-		sctp_ssn_next(in, sid);
+		/* Found it, so mark in stream array. */
+		sctp_ssn_next(ulpq->asoc, in, sid);
 
 		__skb_unlink(pos, &ulpq->lobby);
 
@@ -849,7 +847,6 @@ static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq,
 					     struct sctp_ulpevent *event)
 {
 	__u16 sid, ssn;
-	struct sctp_stream *in;
 
 	/* Check if this message needs ordering.  */
 	if (SCTP_DATA_UNORDERED & event->msg_flags)
@@ -858,10 +855,9 @@ static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq,
 	/* Note: The stream ID must be verified before this routine.  */
 	sid = event->stream;
 	ssn = event->ssn;
-	in  = &ulpq->asoc->ssnmap->in;
 
 	/* Is this the expected SSN for this stream ID?  */
-	if (ssn != sctp_ssn_peek(in, sid)) {
+	if (ssn != sctp_ssn_peek(ulpq->asoc, in, sid)) {
 		/* We've received something out of order, so find where it
 		 * needs to be placed.  We order by stream and then by SSN.
 		 */
@@ -870,7 +866,7 @@ static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq,
 	}
 
 	/* Mark that the next chunk has been found.  */
-	sctp_ssn_next(in, sid);
+	sctp_ssn_next(ulpq->asoc, in, sid);
 
 	/* Go find any other chunks that were waiting for
 	 * ordering.
@@ -888,13 +884,10 @@ static void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid)
 	struct sk_buff *pos, *tmp;
 	struct sctp_ulpevent *cevent;
 	struct sctp_ulpevent *event;
-	struct sctp_stream *in;
 	struct sk_buff_head temp;
 	struct sk_buff_head *lobby = &ulpq->lobby;
 	__u16 csid, cssn;
 
-	in  = &ulpq->asoc->ssnmap->in;
-
 	/* We are holding the chunks by stream, by SSN.  */
 	skb_queue_head_init(&temp);
 	event = NULL;
@@ -912,7 +905,7 @@ static void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid)
 			continue;
 
 		/* see if this ssn has been marked by skipping */
-		if (!SSN_lt(cssn, sctp_ssn_peek(in, csid)))
+		if (!SSN_lt(cssn, sctp_ssn_peek(ulpq->asoc, in, csid)))
 			break;
 
 		__skb_unlink(pos, lobby);
@@ -932,8 +925,9 @@ static void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid)
 		csid = cevent->stream;
 		cssn = cevent->ssn;
 
-		if (csid == sid && cssn == sctp_ssn_peek(in, csid)) {
-			sctp_ssn_next(in, csid);
+		if (csid == sid &&
+		    cssn == sctp_ssn_peek(ulpq->asoc, in, csid)) {
+			sctp_ssn_next(ulpq->asoc, in, csid);
 			__skb_unlink(pos, lobby);
 			__skb_queue_tail(&temp, pos);
 			event = sctp_skb2event(pos);
@@ -955,17 +949,12 @@ static void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid)
  */
 void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn)
 {
-	struct sctp_stream *in;
-
-	/* Note: The stream ID must be verified before this routine.  */
-	in  = &ulpq->asoc->ssnmap->in;
-
 	/* Is this an old SSN?  If so ignore. */
-	if (SSN_lt(ssn, sctp_ssn_peek(in, sid)))
+	if (SSN_lt(ssn, sctp_ssn_peek(ulpq->asoc, in, sid)))
 		return;
 
 	/* Mark that we are no longer expecting this SSN or lower. */
-	sctp_ssn_skip(in, sid, ssn);
+	sctp_ssn_skip(ulpq->asoc, in, sid, ssn);
 
 	/* Go find any other chunks that were waiting for
 	 * ordering and deliver them if needed.
-- 
2.1.0

^ permalink raw reply related

* [PATCHv2 net-next 1/3] sctp: add stream arrays in asoc
From: Xin Long @ 2017-01-03  5:59 UTC (permalink / raw)
  To: network dev, linux-sctp
  Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
In-Reply-To: <cover.1483422833.git.lucien.xin@gmail.com>

This patch is to add streamout and streamin arrays in asoc, initialize
them in sctp_process_init and free them in sctp_association_free.

Stream arrays are used to replace ssnmap to save more stream things in
the next patch.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/net/sctp/structs.h | 18 ++++++++++++++++++
 net/sctp/associola.c       | 19 +++++++++++++++++++
 net/sctp/sm_make_chunk.c   | 17 ++++++++++++++++-
 3 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 87d56cc..549f17d 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1331,6 +1331,18 @@ struct sctp_inithdr_host {
 	__u32 initial_tsn;
 };
 
+struct sctp_stream_out {
+	__u16	ssn;
+	__u8	state;
+};
+
+struct sctp_stream_in {
+	__u16	ssn;
+};
+
+#define SCTP_STREAM_CLOSED		0x00
+#define SCTP_STREAM_OPEN		0x01
+
 /* SCTP_GET_ASSOC_STATS counters */
 struct sctp_priv_assoc_stats {
 	/* Maximum observed rto in the association during subsequent
@@ -1879,6 +1891,12 @@ struct sctp_association {
 	     temp:1,		/* Is it a temporary association? */
 	     prsctp_enable:1;
 
+	/* stream arrays */
+	struct sctp_stream_out *streamout;
+	struct sctp_stream_in *streamin;
+	__u16 streamoutcnt;
+	__u16 streamincnt;
+
 	struct sctp_priv_assoc_stats stats;
 
 	int sent_cnt_removable;
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index d3cc30c..290ec4d 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -361,6 +361,10 @@ void sctp_association_free(struct sctp_association *asoc)
 	/* Free ssnmap storage. */
 	sctp_ssnmap_free(asoc->ssnmap);
 
+	/* Free stream information. */
+	kfree(asoc->streamout);
+	kfree(asoc->streamin);
+
 	/* Clean up the bound address list. */
 	sctp_bind_addr_free(&asoc->base.bind_addr);
 
@@ -1130,6 +1134,8 @@ void sctp_assoc_update(struct sctp_association *asoc,
 	 * has been discarded and needs retransmission.
 	 */
 	if (asoc->state >= SCTP_STATE_ESTABLISHED) {
+		int i;
+
 		asoc->next_tsn = new->next_tsn;
 		asoc->ctsn_ack_point = new->ctsn_ack_point;
 		asoc->adv_peer_ack_point = new->adv_peer_ack_point;
@@ -1139,6 +1145,12 @@ void sctp_assoc_update(struct sctp_association *asoc,
 		 */
 		sctp_ssnmap_clear(asoc->ssnmap);
 
+		for (i = 0; i < asoc->streamoutcnt; i++)
+			asoc->streamout[i].ssn = 0;
+
+		for (i = 0; i < asoc->streamincnt; i++)
+			asoc->streamin[i].ssn = 0;
+
 		/* Flush the ULP reassembly and ordered queue.
 		 * Any data there will now be stale and will
 		 * cause problems.
@@ -1168,6 +1180,13 @@ void sctp_assoc_update(struct sctp_association *asoc,
 			new->ssnmap = NULL;
 		}
 
+		if (!asoc->streamin && !asoc->streamout) {
+			asoc->streamout = new->streamout;
+			asoc->streamin = new->streamin;
+			new->streamout = NULL;
+			new->streamin = NULL;
+		}
+
 		if (!asoc->assoc_id) {
 			/* get a new association id since we don't have one
 			 * yet.
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 9e9690b..eeadeef 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2442,13 +2442,28 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
 	 * association.
 	 */
 	if (!asoc->temp) {
-		int error;
+		int error, i;
+
+		asoc->streamoutcnt = asoc->c.sinit_num_ostreams;
+		asoc->streamincnt = asoc->c.sinit_max_instreams;
 
 		asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
 					       asoc->c.sinit_num_ostreams, gfp);
 		if (!asoc->ssnmap)
 			goto clean_up;
 
+		asoc->streamout = kcalloc(asoc->streamoutcnt,
+					  sizeof(*asoc->streamout), gfp);
+		if (!asoc->streamout)
+			goto clean_up;
+		for (i = 0; i < asoc->streamoutcnt; i++)
+			asoc->streamout[i].state = SCTP_STREAM_OPEN;
+
+		asoc->streamin = kcalloc(asoc->streamincnt,
+					 sizeof(*asoc->streamin), gfp);
+		if (!asoc->streamin)
+			goto clean_up;
+
 		error = sctp_assoc_set_id(asoc, gfp);
 		if (error)
 			goto clean_up;
-- 
2.1.0

^ permalink raw reply related

* [PATCHv2 net-next 0/3] sctp: prepare asoc stream for stream reconf
From: Xin Long @ 2017-01-03  5:59 UTC (permalink / raw)
  To: network dev, linux-sctp
  Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem

sctp stream reconf, described in RFC 6525, needs a structure to
save per stream information in assoc, like stream state.

In the future, sctp stream scheduler also needs it to save some
stream scheduler params and queues.

This patchset is to prepare the stream array in assoc for stream
reconf.

v1->v2:
  put these patches into a smaller group.

Xin Long (3):
  sctp: add stream arrays in asoc
  sctp: replace ssnmap with asoc stream arrays
  sctp: remove asoc ssnmap and ssnmap.c

 include/net/sctp/sctp.h    |   1 -
 include/net/sctp/structs.h |  70 +++++++++----------------
 net/sctp/Makefile          |   3 +-
 net/sctp/associola.c       |  23 ++++++---
 net/sctp/objcnt.c          |   2 -
 net/sctp/sm_make_chunk.c   |  24 ++++++---
 net/sctp/sm_statefuns.c    |   3 +-
 net/sctp/ssnmap.c          | 125 ---------------------------------------------
 net/sctp/ulpqueue.c        |  33 ++++--------
 9 files changed, 69 insertions(+), 215 deletions(-)
 delete mode 100644 net/sctp/ssnmap.c

-- 
2.1.0

^ permalink raw reply

* [PATCHv2 net-next 3/3] sctp: remove asoc ssnmap and ssnmap.c
From: Xin Long @ 2017-01-03  5:59 UTC (permalink / raw)
  To: network dev, linux-sctp
  Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
In-Reply-To: <c752879a5af358c08da949b391416452f1322c43.1483422833.git.lucien.xin@gmail.com>

Since asoc stream arrays has replaced ssnmap, ssnmap is not used any
more, this patch is to remove asoc ssnmap and ssnmap.c.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/net/sctp/sctp.h    |   1 -
 include/net/sctp/structs.h |  33 ------------
 net/sctp/Makefile          |   3 +-
 net/sctp/objcnt.c          |   2 -
 net/sctp/ssnmap.c          | 125 ---------------------------------------------
 5 files changed, 1 insertion(+), 163 deletions(-)
 delete mode 100644 net/sctp/ssnmap.c

diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index d8833a8..598d938 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -283,7 +283,6 @@ extern atomic_t sctp_dbg_objcnt_chunk;
 extern atomic_t sctp_dbg_objcnt_bind_addr;
 extern atomic_t sctp_dbg_objcnt_bind_bucket;
 extern atomic_t sctp_dbg_objcnt_addr;
-extern atomic_t sctp_dbg_objcnt_ssnmap;
 extern atomic_t sctp_dbg_objcnt_datamsg;
 extern atomic_t sctp_dbg_objcnt_keys;
 
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index f81c321..9075d61 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -82,7 +82,6 @@ struct sctp_outq;
 struct sctp_bind_addr;
 struct sctp_ulpq;
 struct sctp_ep_common;
-struct sctp_ssnmap;
 struct crypto_shash;
 
 
@@ -377,35 +376,6 @@ typedef struct sctp_sender_hb_info {
 	__u64 hb_nonce;
 } __packed sctp_sender_hb_info_t;
 
-/*
- *  RFC 2960 1.3.2 Sequenced Delivery within Streams
- *
- *  The term "stream" is used in SCTP to refer to a sequence of user
- *  messages that are to be delivered to the upper-layer protocol in
- *  order with respect to other messages within the same stream.  This is
- *  in contrast to its usage in TCP, where it refers to a sequence of
- *  bytes (in this document a byte is assumed to be eight bits).
- *  ...
- *
- *  This is the structure we use to track both our outbound and inbound
- *  SSN, or Stream Sequence Numbers.
- */
-
-struct sctp_stream {
-	__u16 *ssn;
-	unsigned int len;
-};
-
-struct sctp_ssnmap {
-	struct sctp_stream in;
-	struct sctp_stream out;
-};
-
-struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out,
-				    gfp_t gfp);
-void sctp_ssnmap_free(struct sctp_ssnmap *map);
-void sctp_ssnmap_clear(struct sctp_ssnmap *map);
-
 /* What is the current SSN number for this stream? */
 #define sctp_ssn_peek(asoc, type, sid) \
 	((asoc)->stream##type[sid].ssn)
@@ -1751,9 +1721,6 @@ struct sctp_association {
 	/* Default receive parameters */
 	__u32 default_rcv_context;
 
-	/* This tracks outbound ssn for a given stream.	 */
-	struct sctp_ssnmap *ssnmap;
-
 	/* All outbound chunks go through this structure.  */
 	struct sctp_outq outqueue;
 
diff --git a/net/sctp/Makefile b/net/sctp/Makefile
index 6c4f749..48bfc74 100644
--- a/net/sctp/Makefile
+++ b/net/sctp/Makefile
@@ -11,8 +11,7 @@ sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \
 	  transport.o chunk.o sm_make_chunk.o ulpevent.o \
 	  inqueue.o outqueue.o ulpqueue.o \
 	  tsnmap.o bind_addr.o socket.o primitive.o \
-	  output.o input.o debug.o ssnmap.o auth.o \
-	  offload.o
+	  output.o input.o debug.o auth.o offload.o
 
 sctp_probe-y := probe.o
 
diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c
index 40e7fac..105ac33 100644
--- a/net/sctp/objcnt.c
+++ b/net/sctp/objcnt.c
@@ -51,7 +51,6 @@ SCTP_DBG_OBJCNT(bind_addr);
 SCTP_DBG_OBJCNT(bind_bucket);
 SCTP_DBG_OBJCNT(chunk);
 SCTP_DBG_OBJCNT(addr);
-SCTP_DBG_OBJCNT(ssnmap);
 SCTP_DBG_OBJCNT(datamsg);
 SCTP_DBG_OBJCNT(keys);
 
@@ -67,7 +66,6 @@ static sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = {
 	SCTP_DBG_OBJCNT_ENTRY(bind_addr),
 	SCTP_DBG_OBJCNT_ENTRY(bind_bucket),
 	SCTP_DBG_OBJCNT_ENTRY(addr),
-	SCTP_DBG_OBJCNT_ENTRY(ssnmap),
 	SCTP_DBG_OBJCNT_ENTRY(datamsg),
 	SCTP_DBG_OBJCNT_ENTRY(keys),
 };
diff --git a/net/sctp/ssnmap.c b/net/sctp/ssnmap.c
deleted file mode 100644
index b9c8521..0000000
--- a/net/sctp/ssnmap.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/* SCTP kernel implementation
- * Copyright (c) 2003 International Business Machines, Corp.
- *
- * This file is part of the SCTP kernel implementation
- *
- * These functions manipulate sctp SSN tracker.
- *
- * This SCTP implementation 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, or (at your option)
- * any later version.
- *
- * This SCTP implementation 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * Please send any bug reports or fixes you make to the
- * email address(es):
- *    lksctp developers <linux-sctp@vger.kernel.org>
- *
- * Written or modified by:
- *    Jon Grimm             <jgrimm@us.ibm.com>
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <net/sctp/sctp.h>
-#include <net/sctp/sm.h>
-
-static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
-					    __u16 out);
-
-/* Storage size needed for map includes 2 headers and then the
- * specific needs of in or out streams.
- */
-static inline size_t sctp_ssnmap_size(__u16 in, __u16 out)
-{
-	return sizeof(struct sctp_ssnmap) + (in + out) * sizeof(__u16);
-}
-
-
-/* Create a new sctp_ssnmap.
- * Allocate room to store at least 'len' contiguous TSNs.
- */
-struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out,
-				    gfp_t gfp)
-{
-	struct sctp_ssnmap *retval;
-	int size;
-
-	size = sctp_ssnmap_size(in, out);
-	if (size <= KMALLOC_MAX_SIZE)
-		retval = kmalloc(size, gfp);
-	else
-		retval = (struct sctp_ssnmap *)
-			  __get_free_pages(gfp, get_order(size));
-	if (!retval)
-		goto fail;
-
-	if (!sctp_ssnmap_init(retval, in, out))
-		goto fail_map;
-
-	SCTP_DBG_OBJCNT_INC(ssnmap);
-
-	return retval;
-
-fail_map:
-	if (size <= KMALLOC_MAX_SIZE)
-		kfree(retval);
-	else
-		free_pages((unsigned long)retval, get_order(size));
-fail:
-	return NULL;
-}
-
-
-/* Initialize a block of memory as a ssnmap.  */
-static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
-					    __u16 out)
-{
-	memset(map, 0x00, sctp_ssnmap_size(in, out));
-
-	/* Start 'in' stream just after the map header. */
-	map->in.ssn = (__u16 *)&map[1];
-	map->in.len = in;
-
-	/* Start 'out' stream just after 'in'. */
-	map->out.ssn = &map->in.ssn[in];
-	map->out.len = out;
-
-	return map;
-}
-
-/* Clear out the ssnmap streams.  */
-void sctp_ssnmap_clear(struct sctp_ssnmap *map)
-{
-	size_t size;
-
-	size = (map->in.len + map->out.len) * sizeof(__u16);
-	memset(map->in.ssn, 0x00, size);
-}
-
-/* Dispose of a ssnmap.  */
-void sctp_ssnmap_free(struct sctp_ssnmap *map)
-{
-	int size;
-
-	if (unlikely(!map))
-		return;
-
-	size = sctp_ssnmap_size(map->in.len, map->out.len);
-	if (size <= KMALLOC_MAX_SIZE)
-		kfree(map);
-	else
-		free_pages((unsigned long)map, get_order(size));
-
-	SCTP_DBG_OBJCNT_DEC(ssnmap);
-}
-- 
2.1.0


^ permalink raw reply related

* [PATCHv2 net-next 2/3] sctp: replace ssnmap with asoc stream arrays
From: Xin Long @ 2017-01-03  5:59 UTC (permalink / raw)
  To: network dev, linux-sctp
  Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
In-Reply-To: <684ad8ddd79f23844883dede4c34360ce744dfc3.1483422833.git.lucien.xin@gmail.com>

Stream arrays are used to save per stream information, which includes
ssn for each stream already.

This patch is to replace ssnmap with asoc stream arrays.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/net/sctp/structs.h | 19 ++++++-------------
 net/sctp/associola.c       | 10 ----------
 net/sctp/sm_make_chunk.c   | 11 ++---------
 net/sctp/sm_statefuns.c    |  3 +--
 net/sctp/ulpqueue.c        | 33 +++++++++++----------------------
 5 files changed, 20 insertions(+), 56 deletions(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 549f17d..f81c321 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -407,23 +407,16 @@ void sctp_ssnmap_free(struct sctp_ssnmap *map);
 void sctp_ssnmap_clear(struct sctp_ssnmap *map);
 
 /* What is the current SSN number for this stream? */
-static inline __u16 sctp_ssn_peek(struct sctp_stream *stream, __u16 id)
-{
-	return stream->ssn[id];
-}
+#define sctp_ssn_peek(asoc, type, sid) \
+	((asoc)->stream##type[sid].ssn)
 
 /* Return the next SSN number for this stream.	*/
-static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id)
-{
-	return stream->ssn[id]++;
-}
+#define sctp_ssn_next(asoc, type, sid) \
+	((asoc)->stream##type[sid].ssn++)
 
 /* Skip over this ssn and all below. */
-static inline void sctp_ssn_skip(struct sctp_stream *stream, __u16 id, 
-				 __u16 ssn)
-{
-	stream->ssn[id] = ssn+1;
-}
+#define sctp_ssn_skip(asoc, type, sid, ssn) \
+	((asoc)->stream##type[sid].ssn = ssn + 1)
               
 /*
  * Pointers to address related SCTP functions.
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 290ec4d..ea03270 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -358,9 +358,6 @@ void sctp_association_free(struct sctp_association *asoc)
 
 	sctp_tsnmap_free(&asoc->peer.tsn_map);
 
-	/* Free ssnmap storage. */
-	sctp_ssnmap_free(asoc->ssnmap);
-
 	/* Free stream information. */
 	kfree(asoc->streamout);
 	kfree(asoc->streamin);
@@ -1143,8 +1140,6 @@ void sctp_assoc_update(struct sctp_association *asoc,
 		/* Reinitialize SSN for both local streams
 		 * and peer's streams.
 		 */
-		sctp_ssnmap_clear(asoc->ssnmap);
-
 		for (i = 0; i < asoc->streamoutcnt; i++)
 			asoc->streamout[i].ssn = 0;
 
@@ -1174,11 +1169,6 @@ void sctp_assoc_update(struct sctp_association *asoc,
 
 		asoc->ctsn_ack_point = asoc->next_tsn - 1;
 		asoc->adv_peer_ack_point = asoc->ctsn_ack_point;
-		if (!asoc->ssnmap) {
-			/* Move the ssnmap. */
-			asoc->ssnmap = new->ssnmap;
-			new->ssnmap = NULL;
-		}
 
 		if (!asoc->streamin && !asoc->streamout) {
 			asoc->streamout = new->streamout;
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index eeadeef..78cbd1b 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1527,7 +1527,6 @@ void sctp_chunk_assign_ssn(struct sctp_chunk *chunk)
 {
 	struct sctp_datamsg *msg;
 	struct sctp_chunk *lchunk;
-	struct sctp_stream *stream;
 	__u16 ssn;
 	__u16 sid;
 
@@ -1536,7 +1535,6 @@ void sctp_chunk_assign_ssn(struct sctp_chunk *chunk)
 
 	/* All fragments will be on the same stream */
 	sid = ntohs(chunk->subh.data_hdr->stream);
-	stream = &chunk->asoc->ssnmap->out;
 
 	/* Now assign the sequence number to the entire message.
 	 * All fragments must have the same stream sequence number.
@@ -1547,9 +1545,9 @@ void sctp_chunk_assign_ssn(struct sctp_chunk *chunk)
 			ssn = 0;
 		} else {
 			if (lchunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG)
-				ssn = sctp_ssn_next(stream, sid);
+				ssn = sctp_ssn_next(chunk->asoc, out, sid);
 			else
-				ssn = sctp_ssn_peek(stream, sid);
+				ssn = sctp_ssn_peek(chunk->asoc, out, sid);
 		}
 
 		lchunk->subh.data_hdr->ssn = htons(ssn);
@@ -2447,11 +2445,6 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
 		asoc->streamoutcnt = asoc->c.sinit_num_ostreams;
 		asoc->streamincnt = asoc->c.sinit_max_instreams;
 
-		asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
-					       asoc->c.sinit_num_ostreams, gfp);
-		if (!asoc->ssnmap)
-			goto clean_up;
-
 		asoc->streamout = kcalloc(asoc->streamoutcnt,
 					  sizeof(*asoc->streamout), gfp);
 		if (!asoc->streamout)
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 3382ef2..8a130a7 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -6274,9 +6274,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
 	 * and is invalid.
 	 */
 	ssn = ntohs(data_hdr->ssn);
-	if (ordered && SSN_lt(ssn, sctp_ssn_peek(&asoc->ssnmap->in, sid))) {
+	if (ordered && SSN_lt(ssn, sctp_ssn_peek(asoc, in, sid)))
 		return SCTP_IERROR_PROTO_VIOLATION;
-	}
 
 	/* Send the data up to the user.  Note:  Schedule  the
 	 * SCTP_CMD_CHUNK_ULP cmd before the SCTP_CMD_GEN_SACK, as the SACK
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index 84d0fda..0d8bf26 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -760,11 +760,9 @@ static void sctp_ulpq_retrieve_ordered(struct sctp_ulpq *ulpq,
 	struct sk_buff_head *event_list;
 	struct sk_buff *pos, *tmp;
 	struct sctp_ulpevent *cevent;
-	struct sctp_stream *in;
 	__u16 sid, csid, cssn;
 
 	sid = event->stream;
-	in  = &ulpq->asoc->ssnmap->in;
 
 	event_list = (struct sk_buff_head *) sctp_event2skb(event)->prev;
 
@@ -782,11 +780,11 @@ static void sctp_ulpq_retrieve_ordered(struct sctp_ulpq *ulpq,
 		if (csid < sid)
 			continue;
 
-		if (cssn != sctp_ssn_peek(in, sid))
+		if (cssn != sctp_ssn_peek(ulpq->asoc, in, sid))
 			break;
 
-		/* Found it, so mark in the ssnmap. */
-		sctp_ssn_next(in, sid);
+		/* Found it, so mark in stream array. */
+		sctp_ssn_next(ulpq->asoc, in, sid);
 
 		__skb_unlink(pos, &ulpq->lobby);
 
@@ -849,7 +847,6 @@ static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq,
 					     struct sctp_ulpevent *event)
 {
 	__u16 sid, ssn;
-	struct sctp_stream *in;
 
 	/* Check if this message needs ordering.  */
 	if (SCTP_DATA_UNORDERED & event->msg_flags)
@@ -858,10 +855,9 @@ static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq,
 	/* Note: The stream ID must be verified before this routine.  */
 	sid = event->stream;
 	ssn = event->ssn;
-	in  = &ulpq->asoc->ssnmap->in;
 
 	/* Is this the expected SSN for this stream ID?  */
-	if (ssn != sctp_ssn_peek(in, sid)) {
+	if (ssn != sctp_ssn_peek(ulpq->asoc, in, sid)) {
 		/* We've received something out of order, so find where it
 		 * needs to be placed.  We order by stream and then by SSN.
 		 */
@@ -870,7 +866,7 @@ static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq,
 	}
 
 	/* Mark that the next chunk has been found.  */
-	sctp_ssn_next(in, sid);
+	sctp_ssn_next(ulpq->asoc, in, sid);
 
 	/* Go find any other chunks that were waiting for
 	 * ordering.
@@ -888,13 +884,10 @@ static void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid)
 	struct sk_buff *pos, *tmp;
 	struct sctp_ulpevent *cevent;
 	struct sctp_ulpevent *event;
-	struct sctp_stream *in;
 	struct sk_buff_head temp;
 	struct sk_buff_head *lobby = &ulpq->lobby;
 	__u16 csid, cssn;
 
-	in  = &ulpq->asoc->ssnmap->in;
-
 	/* We are holding the chunks by stream, by SSN.  */
 	skb_queue_head_init(&temp);
 	event = NULL;
@@ -912,7 +905,7 @@ static void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid)
 			continue;
 
 		/* see if this ssn has been marked by skipping */
-		if (!SSN_lt(cssn, sctp_ssn_peek(in, csid)))
+		if (!SSN_lt(cssn, sctp_ssn_peek(ulpq->asoc, in, csid)))
 			break;
 
 		__skb_unlink(pos, lobby);
@@ -932,8 +925,9 @@ static void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid)
 		csid = cevent->stream;
 		cssn = cevent->ssn;
 
-		if (csid = sid && cssn = sctp_ssn_peek(in, csid)) {
-			sctp_ssn_next(in, csid);
+		if (csid = sid &&
+		    cssn = sctp_ssn_peek(ulpq->asoc, in, csid)) {
+			sctp_ssn_next(ulpq->asoc, in, csid);
 			__skb_unlink(pos, lobby);
 			__skb_queue_tail(&temp, pos);
 			event = sctp_skb2event(pos);
@@ -955,17 +949,12 @@ static void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid)
  */
 void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn)
 {
-	struct sctp_stream *in;
-
-	/* Note: The stream ID must be verified before this routine.  */
-	in  = &ulpq->asoc->ssnmap->in;
-
 	/* Is this an old SSN?  If so ignore. */
-	if (SSN_lt(ssn, sctp_ssn_peek(in, sid)))
+	if (SSN_lt(ssn, sctp_ssn_peek(ulpq->asoc, in, sid)))
 		return;
 
 	/* Mark that we are no longer expecting this SSN or lower. */
-	sctp_ssn_skip(in, sid, ssn);
+	sctp_ssn_skip(ulpq->asoc, in, sid, ssn);
 
 	/* Go find any other chunks that were waiting for
 	 * ordering and deliver them if needed.
-- 
2.1.0


^ permalink raw reply related

* [PATCHv2 net-next 1/3] sctp: add stream arrays in asoc
From: Xin Long @ 2017-01-03  5:59 UTC (permalink / raw)
  To: network dev, linux-sctp
  Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
In-Reply-To: <cover.1483422833.git.lucien.xin@gmail.com>

This patch is to add streamout and streamin arrays in asoc, initialize
them in sctp_process_init and free them in sctp_association_free.

Stream arrays are used to replace ssnmap to save more stream things in
the next patch.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/net/sctp/structs.h | 18 ++++++++++++++++++
 net/sctp/associola.c       | 19 +++++++++++++++++++
 net/sctp/sm_make_chunk.c   | 17 ++++++++++++++++-
 3 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 87d56cc..549f17d 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1331,6 +1331,18 @@ struct sctp_inithdr_host {
 	__u32 initial_tsn;
 };
 
+struct sctp_stream_out {
+	__u16	ssn;
+	__u8	state;
+};
+
+struct sctp_stream_in {
+	__u16	ssn;
+};
+
+#define SCTP_STREAM_CLOSED		0x00
+#define SCTP_STREAM_OPEN		0x01
+
 /* SCTP_GET_ASSOC_STATS counters */
 struct sctp_priv_assoc_stats {
 	/* Maximum observed rto in the association during subsequent
@@ -1879,6 +1891,12 @@ struct sctp_association {
 	     temp:1,		/* Is it a temporary association? */
 	     prsctp_enable:1;
 
+	/* stream arrays */
+	struct sctp_stream_out *streamout;
+	struct sctp_stream_in *streamin;
+	__u16 streamoutcnt;
+	__u16 streamincnt;
+
 	struct sctp_priv_assoc_stats stats;
 
 	int sent_cnt_removable;
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index d3cc30c..290ec4d 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -361,6 +361,10 @@ void sctp_association_free(struct sctp_association *asoc)
 	/* Free ssnmap storage. */
 	sctp_ssnmap_free(asoc->ssnmap);
 
+	/* Free stream information. */
+	kfree(asoc->streamout);
+	kfree(asoc->streamin);
+
 	/* Clean up the bound address list. */
 	sctp_bind_addr_free(&asoc->base.bind_addr);
 
@@ -1130,6 +1134,8 @@ void sctp_assoc_update(struct sctp_association *asoc,
 	 * has been discarded and needs retransmission.
 	 */
 	if (asoc->state >= SCTP_STATE_ESTABLISHED) {
+		int i;
+
 		asoc->next_tsn = new->next_tsn;
 		asoc->ctsn_ack_point = new->ctsn_ack_point;
 		asoc->adv_peer_ack_point = new->adv_peer_ack_point;
@@ -1139,6 +1145,12 @@ void sctp_assoc_update(struct sctp_association *asoc,
 		 */
 		sctp_ssnmap_clear(asoc->ssnmap);
 
+		for (i = 0; i < asoc->streamoutcnt; i++)
+			asoc->streamout[i].ssn = 0;
+
+		for (i = 0; i < asoc->streamincnt; i++)
+			asoc->streamin[i].ssn = 0;
+
 		/* Flush the ULP reassembly and ordered queue.
 		 * Any data there will now be stale and will
 		 * cause problems.
@@ -1168,6 +1180,13 @@ void sctp_assoc_update(struct sctp_association *asoc,
 			new->ssnmap = NULL;
 		}
 
+		if (!asoc->streamin && !asoc->streamout) {
+			asoc->streamout = new->streamout;
+			asoc->streamin = new->streamin;
+			new->streamout = NULL;
+			new->streamin = NULL;
+		}
+
 		if (!asoc->assoc_id) {
 			/* get a new association id since we don't have one
 			 * yet.
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 9e9690b..eeadeef 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2442,13 +2442,28 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
 	 * association.
 	 */
 	if (!asoc->temp) {
-		int error;
+		int error, i;
+
+		asoc->streamoutcnt = asoc->c.sinit_num_ostreams;
+		asoc->streamincnt = asoc->c.sinit_max_instreams;
 
 		asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
 					       asoc->c.sinit_num_ostreams, gfp);
 		if (!asoc->ssnmap)
 			goto clean_up;
 
+		asoc->streamout = kcalloc(asoc->streamoutcnt,
+					  sizeof(*asoc->streamout), gfp);
+		if (!asoc->streamout)
+			goto clean_up;
+		for (i = 0; i < asoc->streamoutcnt; i++)
+			asoc->streamout[i].state = SCTP_STREAM_OPEN;
+
+		asoc->streamin = kcalloc(asoc->streamincnt,
+					 sizeof(*asoc->streamin), gfp);
+		if (!asoc->streamin)
+			goto clean_up;
+
 		error = sctp_assoc_set_id(asoc, gfp);
 		if (error)
 			goto clean_up;
-- 
2.1.0


^ permalink raw reply related

* [PATCHv2 net-next 0/3] sctp: prepare asoc stream for stream reconf
From: Xin Long @ 2017-01-03  5:59 UTC (permalink / raw)
  To: network dev, linux-sctp
  Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem

sctp stream reconf, described in RFC 6525, needs a structure to
save per stream information in assoc, like stream state.

In the future, sctp stream scheduler also needs it to save some
stream scheduler params and queues.

This patchset is to prepare the stream array in assoc for stream
reconf.

v1->v2:
  put these patches into a smaller group.

Xin Long (3):
  sctp: add stream arrays in asoc
  sctp: replace ssnmap with asoc stream arrays
  sctp: remove asoc ssnmap and ssnmap.c

 include/net/sctp/sctp.h    |   1 -
 include/net/sctp/structs.h |  70 +++++++++----------------
 net/sctp/Makefile          |   3 +-
 net/sctp/associola.c       |  23 ++++++---
 net/sctp/objcnt.c          |   2 -
 net/sctp/sm_make_chunk.c   |  24 ++++++---
 net/sctp/sm_statefuns.c    |   3 +-
 net/sctp/ssnmap.c          | 125 ---------------------------------------------
 net/sctp/ulpqueue.c        |  33 ++++--------
 9 files changed, 69 insertions(+), 215 deletions(-)
 delete mode 100644 net/sctp/ssnmap.c

-- 
2.1.0


^ permalink raw reply

* [PATCH] ARM: dts: imx: Remove unexistant property
From: Shawn Guo @ 2017-01-03  5:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483123378-20138-1-git-send-email-festevam@gmail.com>

On Fri, Dec 30, 2016 at 04:42:58PM -0200, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam@nxp.com>
> 
> Property 'anatop-enable-bit' does not exist, so just remove it.
> 
> Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH 0/2] Begin auditing SECCOMP_RET_ERRNO return actions
From: Andy Lutomirski @ 2017-01-03  5:57 UTC (permalink / raw)
  To: Tyler Hicks
  Cc: Paul Moore, Eric Paris, Kees Cook, Will Drewry, linux-audit,
	linux-kernel@vger.kernel.org
In-Reply-To: <1483375990-14948-1-git-send-email-tyhicks@canonical.com>

On Mon, Jan 2, 2017 at 8:53 AM, Tyler Hicks <tyhicks@canonical.com> wrote:
> This patch set creates the basis for auditing information specific to a given
> seccomp return action and then starts auditing SECCOMP_RET_ERRNO return
> actions. The audit messages for SECCOMP_RET_ERRNO return actions include the
> errno value that will be returned to userspace.
>

Not that I'm opposed to the idea, but what's the intended purpose?

^ permalink raw reply

* Re: [PATCH 0/2] Begin auditing SECCOMP_RET_ERRNO return actions
From: Andy Lutomirski @ 2017-01-03  5:56 UTC (permalink / raw)
  To: Paul Moore
  Cc: Tyler Hicks, Eric Paris, Kees Cook, Will Drewry, linux-audit,
	linux-kernel@vger.kernel.org
In-Reply-To: <CAHC9VhSOwbY9WEOKZGsx4mf=MAXeudTnQF9nXmKu+OoAs0SDsQ@mail.gmail.com>

On Mon, Jan 2, 2017 at 2:47 PM, Paul Moore <paul@paul-moore.com> wrote:
> On Mon, Jan 2, 2017 at 11:53 AM, Tyler Hicks <tyhicks@canonical.com> wrote:
>> This patch set creates the basis for auditing information specific to a given
>> seccomp return action and then starts auditing SECCOMP_RET_ERRNO return
>> actions. The audit messages for SECCOMP_RET_ERRNO return actions include the
>> errno value that will be returned to userspace.
>
> I'm replying to this patchset posting because it his my inbox first,
> but my comments here apply to both this patchset and the other
> seccomp/audit patchset you posted.
>
> In my experience, we have two or three problems (the count varies
> depending on perspective) when it comes to seccomp filter reporting:
>
> 1. Inability to log all filter actions.
> 2. Inability to selectively enable filtering; e.g. devs want noisy
> logging, users want relative quiet.
> 3. Consistent behavior with audit enabled and disabled.
>
> My current thinking - forgive me, this has been kicking around in my
> head for the better part of six months (longer?) and I haven't
> attempted to code it up - is to create a sysctl knob for a system wide
> seccomp logging threshold that would be applied to the high 16-bits of
> *every* triggered action: if the action was at/below the threshold a
> record would be emitted, otherwise silence.  This should resolve
> problems #1 and #2, and the code should be relatively straightforward
> and small.
>
> As part of the code above, I expect that all seccomp logging would get
> routed through a single logging function (sort of like a better
> implementation of the existing audit_seccomp()) that would check the
> threshold and trigger the logging if needed.  This function could be
> augmented to check for CONFIG_AUDIT and in the case where audit was
> not built into the kernel, a simple printk could be used to log the
> seccomp event; solving problem #3.

Would this not be doable with a seccomp tracepoint and a BPF filter?

--Andy

^ permalink raw reply

* [PATCH v2 3/3] phy: rockchip-inno-usb2: Set EXTCON_USB when EXTCON_CHG_USB_SDP was set
From: Baolin Wang @ 2017-01-03  5:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <23666cc1a5ff123ece5bdbb9821d1eab280d0927.1482307697.git.baolin.wang@linaro.org>

Hi Kison and Heiko,

On 21 December 2016 at 16:12, Baolin Wang <baolin.wang@linaro.org> wrote:
> According to the documentation, we should set the EXTCON_USB when
> one SDP charger connector was reported.
>
> Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
> Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>

Could you apply this patch if there are no other comments? Thanks.

-- 
Baolin.wang
Best Regards

^ permalink raw reply

* Re: [PATCH v2 3/3] phy: rockchip-inno-usb2: Set EXTCON_USB when EXTCON_CHG_USB_SDP was set
From: Baolin Wang @ 2017-01-03  5:54 UTC (permalink / raw)
  To: myungjoo.ham, 최찬우, Chen-Yu Tsai, Kishon,
	Heiko Stübner
  Cc: LKML, linux-arm-kernel, linux-rockchip,
	Linaro Kernel Mailman List, Baolin Wang, Mark Brown, NeilBrown
In-Reply-To: <23666cc1a5ff123ece5bdbb9821d1eab280d0927.1482307697.git.baolin.wang@linaro.org>

Hi Kison and Heiko,

On 21 December 2016 at 16:12, Baolin Wang <baolin.wang@linaro.org> wrote:
> According to the documentation, we should set the EXTCON_USB when
> one SDP charger connector was reported.
>
> Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
> Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>

Could you apply this patch if there are no other comments? Thanks.

-- 
Baolin.wang
Best Regards

^ permalink raw reply

* [PATCH v2 1/6] ARM: mach-mx31_3ds: Remove camera support
From: Shawn Guo @ 2017-01-03  5:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483097613-21481-1-git-send-email-festevam@gmail.com>

On Fri, Dec 30, 2016 at 09:33:28AM -0200, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam@nxp.com>
> 
> Since commit c93cc61475ebbe6e66 ("[media] staging/media: remove deprecated
> mx3 driver") the mx3 camera driver has been removed, so remove the camera
> support from the board file as well.
> 
> Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>

Applied all, thanks.

^ permalink raw reply

* Re: [PATCH v2 0/3] xfs/348: test handling of malformed inode mode
From: Eryu Guan @ 2017-01-03  5:52 UTC (permalink / raw)
  To: Amir Goldstein
  Cc: Darrick J . Wong, Christoph Hellwig, Brian Foster, fstests,
	linux-xfs
In-Reply-To: <1482689376-23553-1-git-send-email-amir73il@gmail.com>

On Sun, Dec 25, 2016 at 08:09:33PM +0200, Amir Goldstein wrote:
> Eryu,
> 
> I beefed up the initial test sent earlier today with more checks
> on mounted fs.
> 
> The original patch testing only xfs_repair remains patch 1 in this series.
> 
> Patch 2 adds fstat tests on mounted fs, which are safe on my test system.
> 
> Patch 3 is explosive. It exposes an XFS assert, but I left a "safety pin"
> that needs to be commented out to reproduce the assert.

My kenrel config doesn't turn DEBUG on, so I don't see a kernel crash :)

I can push this test out after the fix lands in upstream, then I think
there's no need to leave a switch in the test.

Otherwise tests look good to me. But I'd like to have Darrick to review
too, as he had written many fuzzer tests and suggested this test :)

Thanks,
Eryu

> 
> I will soon post my kernel configs and dmesg logs.
> 
> Amir.
> 
> v2:
> - test fstat with malformed inode mode
> - test readlink/readdir with malformed inode mode
> 
> v1:
> - test xfs_repair with malformed inode mode
> 
> Amir Goldstein (3):
>   xfs/348: test handling of invalid inode modes
>   xfs/348: test fstat with malformed inode mode
>   xfs/348: test readlink/readdir with malformed inode mode
> 
>  tests/xfs/348     | 154 +++++++++++++++++++++++++++
>  tests/xfs/348.out | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  tests/xfs/group   |   1 +
>  3 files changed, 467 insertions(+)
>  create mode 100755 tests/xfs/348
>  create mode 100644 tests/xfs/348.out
> 
> -- 
> 2.7.4
> 

^ permalink raw reply

* [PATCH] extcon: Add documentation for EXTCON_CHG_USB_SLOW/FAST
From: Baolin Wang @ 2017-01-03  5:50 UTC (permalink / raw)
  To: myungjoo.ham, cw00.choi
  Cc: linux-kernel, linaro-kernel, baolin.wang, broonie, neilb

Currently there are no documentation for EXTCON_CHG_USB_SLOW/FAST
charger connector. These names don't mean much and no guide to tell
users how to use it, thus try to add documentation to make them clear.

Suggested-by: NeilBrown <neilb@suse.com>
Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
---
 include/linux/extcon.h |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/linux/extcon.h b/include/linux/extcon.h
index 0020123..ceec1f0 100644
--- a/include/linux/extcon.h
+++ b/include/linux/extcon.h
@@ -53,6 +53,10 @@
  * the USB connector, which means EXTCON_CHG_USB_SDP should always
  * appear together with EXTCON_USB. The same as ACA charger connector,
  * EXTCON_CHG_USB_ACA would normally appear with EXTCON_USB_HOST.
+ *
+ * A cable of type EXTCON_CHG_USB_SLOW can provide at least 500mA of
+ * current at 5V. A cable of type EXTCON_CHG_USB_FAST can provide at
+ * least 1A of current at 5V.
  */
 #define EXTCON_CHG_USB_SDP	5	/* Standard Downstream Port */
 #define EXTCON_CHG_USB_DCP	6	/* Dedicated Charging Port */
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v2 2/4] ARM: davinci_all_defconfig: enable video capture as modules
From: Sekhar Nori @ 2017-01-03  5:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161207193137.27947-3-khilman@baylibre.com>

On Thursday 08 December 2016 01:01 AM, Kevin Hilman wrote:
> Enable media support and V4L2 capture, along with video decoders used
> on da850 platforms.
> 
> Tested on da850-lcdk.
> 
> Signed-off-by: Kevin Hilman <khilman@baylibre.com>

Applied to v4.11/defconfig

Thanks,
Sekhar

^ permalink raw reply

* [PATCH 4/4] nfc: Fix hangup of RC-S380* in port100_send_ack()
From: OGAWA Hirofumi @ 2017-01-03  5:48 UTC (permalink / raw)
  To: Samuel Ortiz
  Cc: Aloisio Almeida Jr, Lauro Ramos Venancio, linux-wireless,
	Andrew Morton, linux-kernel
In-Reply-To: <877f6clmn2.fsf_-_@mail.parknet.co.jp>


If port100_send_ack() was called twice or more, it has race to hangup.

  port100_send_ack()          port100_send_ack()
    init_completion()
    [...]
    dev->cmd_cancel = true
                                /* this removes previous from completion */
                                init_completion()
				[...]
                                dev->cmd_cancel = true
                                wait_for_completion()
    /* never be waked up */
    wait_for_completion()

Like above race, this code is not assuming port100_send_ack() is
called twice or more.

To fix, this checks dev->cmd_cancel to know if prior cancel is
in-flight or not. And never be remove prior task from completion by
using reinit_completion(), so this guarantees to be waked up properly
soon or later.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

 drivers/nfc/port100.c |   37 ++++++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff -puN drivers/nfc/port100.c~nfc-port100-hang-fix drivers/nfc/port100.c
--- linux-ibmpc/drivers/nfc/port100.c~nfc-port100-hang-fix	2017-01-03 12:32:13.261785257 +0900
+++ linux-ibmpc-hirofumi/drivers/nfc/port100.c	2017-01-03 12:33:51.965364300 +0900
@@ -726,23 +726,33 @@ static int port100_submit_urb_for_ack(st
 
 static int port100_send_ack(struct port100 *dev)
 {
-	int rc;
+	int rc = 0;
 
 	mutex_lock(&dev->out_urb_lock);
 
-	init_completion(&dev->cmd_cancel_done);
-
-	usb_kill_urb(dev->out_urb);
+	/*
+	 * If prior cancel is in-flight (dev->cmd_cancel == true), we
+	 * can skip to send cancel. Then this will wait the prior
+	 * cancel, or merged into the next cancel rarely if next
+	 * cancel was started before waiting done. In any case, this
+	 * will be waked up soon or later.
+	 */
+	if (!dev->cmd_cancel) {
+		reinit_completion(&dev->cmd_cancel_done);
 
-	dev->out_urb->transfer_buffer = ack_frame;
-	dev->out_urb->transfer_buffer_length = sizeof(ack_frame);
-	rc = usb_submit_urb(dev->out_urb, GFP_KERNEL);
+		usb_kill_urb(dev->out_urb);
 
-	/* Set the cmd_cancel flag only if the URB has been successfully
-	 * submitted. It will be reset by the out URB completion callback
-	 * port100_send_complete().
-	 */
-	dev->cmd_cancel = !rc;
+		dev->out_urb->transfer_buffer = ack_frame;
+		dev->out_urb->transfer_buffer_length = sizeof(ack_frame);
+		rc = usb_submit_urb(dev->out_urb, GFP_KERNEL);
+
+		/*
+		 * Set the cmd_cancel flag only if the URB has been
+		 * successfully submitted. It will be reset by the out
+		 * URB completion callback port100_send_complete().
+		 */
+		dev->cmd_cancel = !rc;
+	}
 
 	mutex_unlock(&dev->out_urb_lock);
 
@@ -929,8 +939,8 @@ static void port100_send_complete(struct
 	struct port100 *dev = urb->context;
 
 	if (dev->cmd_cancel) {
+		complete_all(&dev->cmd_cancel_done);
 		dev->cmd_cancel = false;
-		complete(&dev->cmd_cancel_done);
 	}
 
 	switch (urb->status) {
@@ -1546,6 +1556,7 @@ static int port100_probe(struct usb_inte
 			    PORT100_COMM_RF_HEAD_MAX_LEN;
 	dev->skb_tailroom = PORT100_FRAME_TAIL_LEN;
 
+	init_completion(&dev->cmd_cancel_done);
 	INIT_WORK(&dev->cmd_complete_work, port100_wq_cmd_complete);
 
 	/* The first thing to do with the Port-100 is to set the command type
_

-- 
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

^ permalink raw reply

* [PATCH resend 3/4] nfc: Fix RC-S380* needs zero-length packet
From: OGAWA Hirofumi @ 2017-01-03  5:48 UTC (permalink / raw)
  To: Samuel Ortiz
  Cc: Aloisio Almeida Jr, Lauro Ramos Venancio, linux-wireless,
	Andrew Morton, linux-kernel
In-Reply-To: <87bmvolmnt.fsf@mail.parknet.co.jp>


If sent packet size is wMaxPacketSize boundary, this device doesn't
answer. To fix this, we have to send zero-length packet in usb spec.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

 drivers/nfc/port100.c |    1 +
 1 file changed, 1 insertion(+)

diff -puN drivers/nfc/port100.c~nfc-need-zero-packet drivers/nfc/port100.c
--- linux-ibmpc/drivers/nfc/port100.c~nfc-need-zero-packet	2016-12-31 18:27:14.814753508 +0900
+++ linux-ibmpc-hirofumi/drivers/nfc/port100.c	2016-12-31 18:32:12.928334607 +0900
@@ -1540,6 +1540,7 @@ static int port100_probe(struct usb_inte
 	usb_fill_bulk_urb(dev->out_urb, dev->udev,
 			  usb_sndbulkpipe(dev->udev, out_endpoint),
 			  NULL, 0, port100_send_complete, dev);
+	dev->out_urb->transfer_flags = URB_ZERO_PACKET;
 
 	dev->skb_headroom = PORT100_FRAME_HEADER_LEN +
 			    PORT100_COMM_RF_HEAD_MAX_LEN;
_

-- 
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

^ permalink raw reply

* [PATCH resend 2/4] nfc: Send same info for both of NFC_CMD_GET_DEVICE and NFC_EVENT_DEVICE_ADDED
From: OGAWA Hirofumi @ 2017-01-03  5:47 UTC (permalink / raw)
  To: Samuel Ortiz
  Cc: Aloisio Almeida Jr, Lauro Ramos Venancio, linux-wireless,
	Andrew Morton, linux-kernel
In-Reply-To: <87ful0lmop.fsf@mail.parknet.co.jp>


Now, NFC_EVENT_DEVICE_ADDED doesn't send NFC_ATTR_RF_MODE. But
NFC_CMD_GET_DEVICE send.

To get NFC_ATTR_RF_MODE, we have to call NFC_CMD_GET_DEVICE just for
NFC_ATTR_RF_MODE when get NFC_EVENT_DEVICE_ADDED.

This fixes those inconsistent.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

 net/nfc/netlink.c |   22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff -puN net/nfc/netlink.c~nfc-send-same-info net/nfc/netlink.c
--- linux/net/nfc/netlink.c~nfc-send-same-info	2016-12-18 22:16:55.805686290 +0900
+++ linux-hirofumi/net/nfc/netlink.c	2016-12-18 22:16:55.806686296 +0900
@@ -311,6 +311,17 @@ free_msg:
 	return -EMSGSIZE;
 }
 
+static int nfc_genl_setup_device_added(struct nfc_dev *dev, struct sk_buff *msg)
+{
+	if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
+	    nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
+	    nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
+	    nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up) ||
+	    nla_put_u8(msg, NFC_ATTR_RF_MODE, dev->rf_mode))
+		return -1;
+	return 0;
+}
+
 int nfc_genl_device_added(struct nfc_dev *dev)
 {
 	struct sk_buff *msg;
@@ -325,10 +336,7 @@ int nfc_genl_device_added(struct nfc_dev
 	if (!hdr)
 		goto free_msg;
 
-	if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
-	    nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
-	    nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
-	    nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up))
+	if (nfc_genl_setup_device_added(dev, msg))
 		goto nla_put_failure;
 
 	genlmsg_end(msg, hdr);
@@ -604,11 +612,7 @@ static int nfc_genl_send_device(struct s
 	if (cb)
 		genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
 
-	if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
-	    nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
-	    nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
-	    nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up) ||
-	    nla_put_u8(msg, NFC_ATTR_RF_MODE, dev->rf_mode))
+	if (nfc_genl_setup_device_added(dev, msg))
 		goto nla_put_failure;
 
 	genlmsg_end(msg, hdr);
_

-- 
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

^ permalink raw reply

* [PATCH resend 1/4] nfc: Add support RC-S380P to port100
From: OGAWA Hirofumi @ 2017-01-03  5:47 UTC (permalink / raw)
  To: Samuel Ortiz
  Cc: Aloisio Almeida Jr, Lauro Ramos Venancio, linux-wireless,
	Andrew Morton, linux-kernel


Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

 drivers/nfc/port100.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff -puN drivers/nfc/port100.c~nfc-add-rcs380p drivers/nfc/port100.c
--- linux/drivers/nfc/port100.c~nfc-add-rcs380p	2016-12-18 22:16:53.503673411 +0900
+++ linux-hirofumi/drivers/nfc/port100.c	2016-12-18 22:16:53.504673416 +0900
@@ -21,8 +21,9 @@
 
 #define VERSION "0.1"
 
-#define SONY_VENDOR_ID    0x054c
-#define RCS380_PRODUCT_ID 0x06c1
+#define SONY_VENDOR_ID		0x054c
+#define RCS380S_PRODUCT_ID	0x06c1
+#define RCS380P_PRODUCT_ID	0x06c3
 
 #define PORT100_PROTOCOLS (NFC_PROTO_JEWEL_MASK    | \
 			   NFC_PROTO_MIFARE_MASK   | \
@@ -1477,7 +1478,8 @@ static struct nfc_digital_ops port100_di
 };
 
 static const struct usb_device_id port100_table[] = {
-	{ USB_DEVICE(SONY_VENDOR_ID, RCS380_PRODUCT_ID), },
+	{ USB_DEVICE(SONY_VENDOR_ID, RCS380S_PRODUCT_ID), },
+	{ USB_DEVICE(SONY_VENDOR_ID, RCS380P_PRODUCT_ID), },
 	{ }
 };
 MODULE_DEVICE_TABLE(usb, port100_table);
_

-- 
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

^ permalink raw reply

* Re: [PATCH v4 0/9] mm/swap: Regular page swap optimizations
From: Huang, Ying @ 2017-01-03  5:43 UTC (permalink / raw)
  To: Minchan Kim
  Cc: Jan Kara, Tim Chen, Andrew Morton, Ying Huang, dave.hansen, ak,
	aaron.lu, linux-mm, linux-kernel, Hugh Dickins, Shaohua Li,
	Rik van Riel, Andrea Arcangeli, Kirill A . Shutemov,
	Vladimir Davydov, Johannes Weiner, Michal Hocko, Hillf Danton,
	Christian Borntraeger, Jonathan Corbet, Peter Zijlstra,
	Nicholas Piggin
In-Reply-To: <20170103043411.GA15657@bbox>

Hi, Minchan,

Minchan Kim <minchan@kernel.org> writes:

> Hi Jan,
>
> On Mon, Jan 02, 2017 at 04:48:41PM +0100, Jan Kara wrote:
>> Hi,
>> 
>> On Tue 27-12-16 16:45:03, Minchan Kim wrote:
>> > > Patch 3 splits the swap cache radix tree into 64MB chunks, reducing
>> > >         the rate that we have to contende for the radix tree.
>> > 
>> > To me, it's rather hacky. I think it might be common problem for page cache
>> > so can we think another generalized way like range_lock? Ccing Jan.
>> 
>> I agree on the hackyness of the patch and that page cache would suffer with
>> the same contention (although the files are usually smaller than swap so it
>> would not be that visible I guess). But I don't see how range lock would
>> help here - we need to serialize modifications of the tree structure itself
>> and that is difficult to achieve with the range lock. So what you would
>> need is either a different data structure for tracking swap cache entries
>> or a finer grained locking of the radix tree.
>
> Thanks for the comment, Jan.
>
> I think there are more general options. One is to shrink batching pages like
> Mel and Tim had approached.
>
> https://patchwork.kernel.org/patch/9008421/
> https://patchwork.kernel.org/patch/9322793/

This helps to reduce the lock contention on radix tree of swap cache.
But splitting swap cache has much better performance.  So we switched
from that solution to current solution.

> Or concurrent page cache by peter.
>
> https://www.kernel.org/doc/ols/2007/ols2007v2-pages-311-318.pdf

I think this is good, it helps swap and file cache.  But I don't know
whether other people want to go this way and how much effort will be
needed.

In contrast, splitting swap cache is quite simple, for implementation
and review.  And the effect is good.

Best Regards,
Huang, Ying

> Ccing Nick who might have an interest on lockless page cache.
>
> Thanks.

^ permalink raw reply


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.