Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH iproute2] iproute: make clang happy
From: Stephen Hemminger @ 2018-08-20 22:50 UTC (permalink / raw)
  To: Mahesh Bandewar; +Cc: netdev, Mahesh Bandewar
In-Reply-To: <20180820214215.218127-1-mahesh@bandewar.net>

On Mon, 20 Aug 2018 14:42:15 -0700
Mahesh Bandewar <mahesh@bandewar.net> wrote:

>  
>  		if (is_json_context()) {
> +			json_writer_t *jw;
> +
>  			open_json_object("bittiming");
>  			print_int(PRINT_ANY, "bitrate", NULL, bt->bitrate);
> -			jsonw_float_field_fmt(get_json_writer(),
> -					      "sample_point", "%.3f",
> -					      (float) bt->sample_point / 1000.);
> +			jw = get_json_writer();
> +			jsonw_name(jw, "sample_point");
> +			jsonw_printf(jw, "%.3f",
> +				     (float) bt->sample_point / 1000);

I think it would be better to get rid of the is_json_context() here in  the CAN code
and just use the print_json functions completely.  Most of the other code is able to
do that already.

^ permalink raw reply

* Re: [PATCH] dt-bindings: can: rcar_can: Add r8a774a1 support
From: Rob Herring @ 2018-08-20 22:32 UTC (permalink / raw)
  To: Fabrizio Castro
  Cc: Wolfgang Grandegger, Marc Kleine-Budde, Mark Rutland,
	Fabrizio Castro, David S. Miller, linux-can, netdev, devicetree,
	Simon Horman, Geert Uytterhoeven, Chris Paterson, Biju Das,
	linux-renesas-soc, linux-kernel
In-Reply-To: <1534516703-11448-1-git-send-email-fabrizio.castro@bp.renesas.com>

On Fri, 17 Aug 2018 15:38:23 +0100, Fabrizio Castro wrote:
> Document RZ/G2M (r8a774a1) SoC bindings.
> 
> Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> Reviewed-by: Biju Das <biju.das@bp.renesas.com>
> ---
> This patch applies on top of next-20180817
> 
>  Documentation/devicetree/bindings/net/can/rcar_can.txt | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH iproute2] iproute: make clang happy
From: Mahesh Bandewar @ 2018-08-20 21:42 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Mahesh Bandewar

From: Mahesh Bandewar <maheshb@google.com>

These are primarily fixes for "string is not string literal" warnings
/ errors (with -Werror -Wformat-nonliteral). This should be a no-op
change. I had to replace couple of print helper functions with the
code they call as it was becoming harder to eliminate these warnings,
however these helpers were used only at couple of places, so no
major change as such.

Signed-off-by: Mahesh Bandewar <maheshb@google.com>
---
 include/json_writer.h |  2 --
 ip/iplink_can.c       | 19 ++++++++++++-------
 lib/color.c           |  1 +
 lib/json_print.c      |  1 +
 lib/json_writer.c     | 15 +--------------
 misc/ss.c             |  3 ++-
 tc/m_ematch.c         |  1 +
 7 files changed, 18 insertions(+), 24 deletions(-)

diff --git a/include/json_writer.h b/include/json_writer.h
index 9ab88e1dbdd9..a111cc62e7b2 100644
--- a/include/json_writer.h
+++ b/include/json_writer.h
@@ -59,8 +59,6 @@ void jsonw_luint_field(json_writer_t *self, const char *prop,
 			unsigned long int num);
 void jsonw_lluint_field(json_writer_t *self, const char *prop,
 			unsigned long long int num);
-void jsonw_float_field_fmt(json_writer_t *self, const char *prop,
-			   const char *fmt, double val);
 
 /* Collections */
 void jsonw_start_object(json_writer_t *self);
diff --git a/ip/iplink_can.c b/ip/iplink_can.c
index 587413da15c4..c0deeb1f1fcf 100644
--- a/ip/iplink_can.c
+++ b/ip/iplink_can.c
@@ -316,11 +316,14 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
 		struct can_bittiming *bt = RTA_DATA(tb[IFLA_CAN_BITTIMING]);
 
 		if (is_json_context()) {
+			json_writer_t *jw;
+
 			open_json_object("bittiming");
 			print_int(PRINT_ANY, "bitrate", NULL, bt->bitrate);
-			jsonw_float_field_fmt(get_json_writer(),
-					      "sample_point", "%.3f",
-					      (float) bt->sample_point / 1000.);
+			jw = get_json_writer();
+			jsonw_name(jw, "sample_point");
+			jsonw_printf(jw, "%.3f",
+				     (float) bt->sample_point / 1000);
 			print_int(PRINT_ANY, "tq", NULL, bt->tq);
 			print_int(PRINT_ANY, "prop_seg", NULL, bt->prop_seg);
 			print_int(PRINT_ANY, "phase_seg1",
@@ -415,12 +418,14 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
 			RTA_DATA(tb[IFLA_CAN_DATA_BITTIMING]);
 
 		if (is_json_context()) {
+			json_writer_t *jw;
+
 			open_json_object("data_bittiming");
 			print_int(PRINT_JSON, "bitrate", NULL, dbt->bitrate);
-			jsonw_float_field_fmt(get_json_writer(),
-					      "sample_point",
-					      "%.3f",
-					      (float) dbt->sample_point / 1000.);
+			jw = get_json_writer();
+			jsonw_name(jw, "sample_point");
+			jsonw_printf(jw, "%.3f",
+				     (float) dbt->sample_point / 1000.);
 			print_int(PRINT_JSON, "tq", NULL, dbt->tq);
 			print_int(PRINT_JSON, "prop_seg", NULL, dbt->prop_seg);
 			print_int(PRINT_JSON, "phase_seg1",
diff --git a/lib/color.c b/lib/color.c
index eaf69e74d673..e5406294dfc4 100644
--- a/lib/color.c
+++ b/lib/color.c
@@ -132,6 +132,7 @@ void set_color_palette(void)
 		is_dark_bg = 1;
 }
 
+__attribute__((format(printf, 3, 4)))
 int color_fprintf(FILE *fp, enum color_attr attr, const char *fmt, ...)
 {
 	int ret = 0;
diff --git a/lib/json_print.c b/lib/json_print.c
index 5dc41bfabfd4..77902824a738 100644
--- a/lib/json_print.c
+++ b/lib/json_print.c
@@ -100,6 +100,7 @@ void close_json_array(enum output_type type, const char *str)
  * functions handling different types
  */
 #define _PRINT_FUNC(type_name, type)					\
+	__attribute__((format(printf, 4, 0)))				\
 	void print_color_##type_name(enum output_type t,		\
 				     enum color_attr color,		\
 				     const char *key,			\
diff --git a/lib/json_writer.c b/lib/json_writer.c
index aa9ce1c65e51..68890b34ee92 100644
--- a/lib/json_writer.c
+++ b/lib/json_writer.c
@@ -152,6 +152,7 @@ void jsonw_name(json_writer_t *self, const char *name)
 		putc(' ', self->out);
 }
 
+__attribute__((format(printf, 2, 3)))
 void jsonw_printf(json_writer_t *self, const char *fmt, ...)
 {
 	va_list ap;
@@ -205,11 +206,6 @@ void jsonw_null(json_writer_t *self)
 	jsonw_printf(self, "null");
 }
 
-void jsonw_float_fmt(json_writer_t *self, const char *fmt, double num)
-{
-	jsonw_printf(self, fmt, num);
-}
-
 void jsonw_float(json_writer_t *self, double num)
 {
 	jsonw_printf(self, "%g", num);
@@ -274,15 +270,6 @@ void jsonw_float_field(json_writer_t *self, const char *prop, double val)
 	jsonw_float(self, val);
 }
 
-void jsonw_float_field_fmt(json_writer_t *self,
-			   const char *prop,
-			   const char *fmt,
-			   double val)
-{
-	jsonw_name(self, prop);
-	jsonw_float_fmt(self, fmt, val);
-}
-
 void jsonw_uint_field(json_writer_t *self, const char *prop, unsigned int num)
 {
 	jsonw_name(self, prop);
diff --git a/misc/ss.c b/misc/ss.c
index 41e7762bb61f..93b1baf5dc40 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -976,6 +976,7 @@ static int buf_update(int len)
 }
 
 /* Append content to buffer as part of the current field */
+__attribute__((format(printf, 1, 2)))
 static void out(const char *fmt, ...)
 {
 	struct column *f = current_field;
@@ -1093,7 +1094,7 @@ static void print_header(void)
 {
 	while (!field_is_last(current_field)) {
 		if (!current_field->disabled)
-			out(current_field->header);
+			out("%s", current_field->header);
 		field_next();
 	}
 }
diff --git a/tc/m_ematch.c b/tc/m_ematch.c
index ace4b3dd738b..a524b520b276 100644
--- a/tc/m_ematch.c
+++ b/tc/m_ematch.c
@@ -277,6 +277,7 @@ static int flatten_tree(struct ematch *head, struct ematch *tree)
 	return count;
 }
 
+__attribute__((format(printf, 5, 6)))
 int em_parse_error(int err, struct bstr *args, struct bstr *carg,
 		   struct ematch_util *e, char *fmt, ...)
 {
-- 
2.18.0.865.gffc8e1a3cd6-goog

^ permalink raw reply related

* Re: [PATCH v2 06/29] mtd: Add support for reading MTD devices via the nvmem API
From: Alban @ 2018-08-20 21:27 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Aban Bedel, Srinivas Kandagatla, Bartosz Golaszewski,
	Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Marek Vasut, Richard Weinberger, Grygorii Strashko,
	David S . Miller, Naren, Mauro Carvalho Chehab, Andrew Morton,
	Lukas Wunner, Dan 
In-Reply-To: <20180820202038.5d3dc195@bbrezillon>

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

On Mon, 20 Aug 2018 20:20:38 +0200
Boris Brezillon <boris.brezillon@bootlin.com> wrote:

> On Mon, 20 Aug 2018 11:43:34 +0100
> Srinivas Kandagatla <srinivas.kandagatla@linaro.org> wrote:
> 
> > 
> > Overall am still not able to clear visualize on how MTD bindings with 
> > nvmem cells would look in both partition and un-partition usecases?
> > An example DT would be nice here!!  
> 
> Something along those lines:

We must also have a compatible string on the nvmem-cells node to make
sure we don't clash with the old style MTD partitions, or some other
device specific binding.

> 
> 	mtdnode {
> 		nvmem-cells {
                        compatible = "nvmem-cells";
> 			#address-cells = <1>;
> 			#size-cells = <1>;
> 
> 			cell@0 {
> 				reg = <0x0 0x14>;
> 			};
> 		};
> 
> 		partitions {
> 			compatible = "fixed-partitions";
> 			#address-cells = <1>;
> 			#size-cells = <1>;
> 
> 			partition@0 {
> 				reg = <0x0 0x20000>;
> 
> 				nvmem-cells {
                                        compatible = "nvmem-cells";
> 					#address-cells = <1>;
> 					#size-cells = <1>;
> 
> 					cell@0 {
> 						reg = <0x0 0x10>;
> 					};
> 				};
> 			};
> 		};
> 	};


Alban

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* Re: [bpf-next RFC 0/3] Introduce eBPF flow dissector
From: Alexei Starovoitov @ 2018-08-20 20:52 UTC (permalink / raw)
  To: Petar Penkov
  Cc: netdev, davem, ast, daniel, simon.horman, Petar Penkov, willemb
In-Reply-To: <20180816164423.14368-1-peterpenkov96@gmail.com>

On Thu, Aug 16, 2018 at 09:44:20AM -0700, Petar Penkov wrote:
> From: Petar Penkov <ppenkov@google.com>
> 
> This patch series hardens the RX stack by allowing flow dissection in BPF,
> as previously discussed [1]. Because of the rigorous checks of the BPF
> verifier, this provides significant security guarantees. In particular, the
> BPF flow dissector cannot get inside of an infinite loop, as with
> CVE-2013-4348, because BPF programs are guaranteed to terminate. It cannot
> read outside of packet bounds, because all memory accesses are checked.
> Also, with BPF the administrator can decide which protocols to support,
> reducing potential attack surface. Rarely encountered protocols can be
> excluded from dissection and the program can be updated without kernel
> recompile or reboot if a bug is discovered.
> 
> Patch 1 adds infrastructure to execute a BPF program in __skb_flow_dissect.
> This includes a new BPF program and attach type.
> 
> Patch 2 adds a flow dissector program in BPF. This parses most protocols in
> __skb_flow_dissect in BPF for a subset of flow keys (basic, control, ports,
> and address types).
> 
> Patch 3 adds a selftest that attaches the BPF program to the flow dissector
> and sends traffic with different levels of encapsulation.

Overall I fully support the direction. Few things to consider:

> This RFC patchset exposes a few design considerations:
> 
> 1/ Because the flow dissector key definitions live in
> include/linux/net/flow_dissector.h, they are not visible from userspace,
> and the flow keys definitions need to be copied in the BPF program.

I don't think copy-paste avoids the issue of uapi.
Anything used by BPF program is uapi.
The only exception is offsets of kernel internal structures
passed into bpf_probe_read().
So we have several options:
1. be honest and say 'struct flow_dissect_key*' is now uapi
2. wrap all of them into 'struct bpf_flow_dissect_key*' and do rewrites
  when/if 'struct flow_dissect_key*' changes
3. wait for BTF to solve it for tracing use case and for this one two.
The idea is that kernel internal structs can be defined in bpf prog
and since they will be described precisely in BTF that comes with the prog
the kernel can validate that prog's BTF matches what kernel thinks it has.
imo that's the most flexible, but BTF for all of vmlinux won't be ready
tomorrow and looks like this patch set is ready to go, so I would go with 1 or 2.

> 2/ An alternative to adding a new hook would have been to attach flow
> dissection programs at the XDP hook. Because this hook is executed before
> GRO, it would have to execute on every MSS, which would be more
> computationally expensive. Furthermore, the XDP hook is executed before an
> SKB has been allocated and there is no clear way to move the dissected keys
> into the SKB after it has been allocated. Eventually, perhaps a single pass
> can implement both GRO and flow dissection -- but napi_gro_cb shows that a
> lot more flow state would need to be parsed for this.

global flow_dissect bpf hook semantics are problematic for testing.
like patch 3 test affects the whole system including all containers.
should the hook be per-netns or may be per netdevice?

> 3/ The BPF program cannot use direct packet access everywhere because it
> uses an offset, initially supplied by the flow dissector.  Because the
> initial value of this non-constant offset comes from outside of the
> program, the verifier does not know what its value is, and it cannot verify
> that it is within packet bounds. Therefore, direct packet access programs
> get rejected.

this part doesn't seem to match the code.
direct packet access is allowed and usable even for fragmented skbs.
in such case only linear part of skb is in "direct access".

Last bit, I'm curious about, how the 'demo' flow dissector program
from patch 2 fairs vs in-kernel dissector when performance tested?

^ permalink raw reply

* Re: r8169 needs CONFIG_REALTEK_PHY
From: Florian Fainelli @ 2018-08-20 20:39 UTC (permalink / raw)
  To: Marc Dionne, hkallweit1, netdev, David Miller
In-Reply-To: <CAB9dFdurBUDvDkfFdK5aqAnM5J0MP7r5K83HbQRNJP_wWdAvvw@mail.gmail.com>

On 08/20/2018 12:44 PM, Marc Dionne wrote:
> The r8169 adapter in one of my machines was not working after updating
> to a current kernel from the merge window, which was fixed by enabling
> CONFIG_REALTEK_PHY.
> 
> So in addition to "select PHYLIB", should CONFIG_R8169 not also be
> doing "select CONFIG_REALTEK_PHY" ?

This is fixed in Linus' tree now with:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bfdd19ad80f203f42f05fd32a31c678c9c524ef9
-- 
Florian

^ permalink raw reply

* Re: r8169 needs CONFIG_REALTEK_PHY
From: Heiner Kallweit @ 2018-08-20 20:38 UTC (permalink / raw)
  To: Marc Dionne, netdev, David Miller
In-Reply-To: <CAB9dFdurBUDvDkfFdK5aqAnM5J0MP7r5K83HbQRNJP_wWdAvvw@mail.gmail.com>

On 20.08.2018 21:44, Marc Dionne wrote:
> The r8169 adapter in one of my machines was not working after updating
> to a current kernel from the merge window, which was fixed by enabling
> CONFIG_REALTEK_PHY.
> 
> So in addition to "select PHYLIB", should CONFIG_R8169 not also be
> doing "select CONFIG_REALTEK_PHY" ?
> 
This fix was applied already and is included in latest linux-next.
bfdd19ad80f2 ("r8169: add missing Kconfig dependency")

> Marc
> 

^ permalink raw reply

* Re: [PATCH net-next v8 0/7] net: vhost: improve performance when enable busyloop
From: Michael S. Tsirkin @ 2018-08-20 20:34 UTC (permalink / raw)
  To: xiangxia.m.yue; +Cc: jasowang, makita.toshiaki, virtualization, netdev
In-Reply-To: <1534680686-3108-1-git-send-email-xiangxia.m.yue@gmail.com>

On Sun, Aug 19, 2018 at 05:11:19AM -0700, xiangxia.m.yue@gmail.com wrote:
> From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> 
> This patches improve the guest receive performance.
> On the handle_tx side, we poll the sock receive queue
> at the same time. handle_rx do that in the same way.
> 
> For more performance report, see patch 4, 6, 7


Thanks for the patches. I'm traveling this week,
will do my best to review next week.

> Tonghao Zhang (7):
>   net: vhost: lock the vqs one by one
>   net: vhost: replace magic number of lock annotation
>   net: vhost: factor out busy polling logic to vhost_net_busy_poll()
>   net: vhost: add rx busy polling in tx path
>   net: vhost: introduce bitmap for vhost_poll
>   net: vhost: disable rx wakeup during tx busypoll
>   net: vhost: make busyloop_intr more accurate
> 
>  drivers/vhost/net.c   | 169 +++++++++++++++++++++++++++++++-------------------
>  drivers/vhost/vhost.c |  41 ++++++------
>  drivers/vhost/vhost.h |   7 ++-
>  3 files changed, 133 insertions(+), 84 deletions(-)
> 
> -- 
> 1.8.3.1

^ permalink raw reply

* Re: Checkpatch False positive
From: Jeff Kirsher @ 2018-08-20 20:32 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: Andy Whitcroft, Joe Perches, netdev, Linux Docs
In-Reply-To: <20180820202250.GA6345@bombadil.infradead.org>

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

On Mon, 2018-08-20 at 13:22 -0700, Matthew Wilcox wrote:
> On Mon, Aug 20, 2018 at 01:21:30PM -0700, Jeff Kirsher wrote:
> > Checkpatch.pl should probably exclude *.rst files from the SPDX
> > License
> > Identifier check, since they are documentational files, like
> > *.txt. 
> 
> They're still copyrighted work, so they should still have SPDX tags
> to identify their license.
> 
> checkpatch has:
> 
>                                 } elsif ($realfile =~ /\.rst$/) {
>                                         $comment = '..';
> 
> so we're explicitly including rst files in the checking for now.

Ah, sorry.  I did not catch that they started to include SPDX-License-
Identifiers for RST files, thanks Matthew.

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

^ permalink raw reply

* [RFC RFT PATCH v4 4/4] gpiolib: Implement fast processing path in get/set array
From: Janusz Krzysztofik @ 2018-08-20 23:43 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Jonathan Corbet, Miguel Ojeda Sandonis, Peter Korsgaard,
	Peter Rosin, Ulf Hansson, Andrew Lunn, Florian Fainelli,
	David S. Miller, Dominik Brodowski, Kishon Vijay Abraham I,
	Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
	Hartmut Knaack, Peter Meerwald-Stadler, Greg Kroah-Hartman,
	Jiri Slaby, linux-gpio, linux-doc, linux-i2c
In-Reply-To: <20180820234341.5271-1-jmkrzyszt@gmail.com>

Certain GPIO descriptor arrays returned by gpio_get_array() may contain
information on direct mapping of array members to pins of a single GPIO
chip in hardware order.  In such cases, bitmaps of values can be passed
directly from/to the chip's .get/set_multiple() callbacks without
wasting time on iterations.

Add respective code to gpiod_get/set_array_bitmap_complex() functions.
Pins not applicable for fast path are processed as before, skipping
over the 'fast' ones.

Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
---
 Documentation/driver-api/gpio/board.rst    | 15 ++++++
 Documentation/driver-api/gpio/consumer.rst |  8 +++
 drivers/gpio/gpiolib.c                     | 87 ++++++++++++++++++++++++++++--
 3 files changed, 105 insertions(+), 5 deletions(-)

diff --git a/Documentation/driver-api/gpio/board.rst b/Documentation/driver-api/gpio/board.rst
index 2c112553df84..c66821e033c2 100644
--- a/Documentation/driver-api/gpio/board.rst
+++ b/Documentation/driver-api/gpio/board.rst
@@ -193,3 +193,18 @@ And the table can be added to the board code as follows::
 
 The line will be hogged as soon as the gpiochip is created or - in case the
 chip was created earlier - when the hog table is registered.
+
+Arrays of pins
+--------------
+In addition to requesting pins belonging to a function one by one, a device may
+also request an array of pins assigned to the function.  The way those pins are
+mapped to the device determines if the array qualifies for fast bitmap
+processing.  If yes, a bitmap is passed over get/set array functions directly
+between a caller and a respective .get/set_multiple() callback of a GPIO chip.
+
+In order to qualify for fast bitmap processing, the pin mapping must meet the
+following requirements:
+- it must belong to the same chip as other 'fast' pins of the function,
+- its index within the function must match its hardware number within the chip.
+
+Open drain and open source pins are excluded from fast bitmap output processing.
diff --git a/Documentation/driver-api/gpio/consumer.rst b/Documentation/driver-api/gpio/consumer.rst
index 0afd95a12b10..cf992e5ab976 100644
--- a/Documentation/driver-api/gpio/consumer.rst
+++ b/Documentation/driver-api/gpio/consumer.rst
@@ -388,6 +388,14 @@ array_info should be set to NULL.
 Note that for optimal performance GPIOs belonging to the same chip should be
 contiguous within the array of descriptors.
 
+Still better performance may be achieved if array indexes of the descriptors
+match hardware pin numbers of a single chip.  If an array passed to a get/set
+array function matches the one obtained from gpiod_get_array() and array_info
+associated with the array is also passed, the function may take a fast bitmap
+processing path, passing the value_bitmap argument directly to the respective
+.get/set_multiple() callback of the chip.  That allows for utilization of GPIO
+banks as data I/O ports without much loss of performance.
+
 The return value of gpiod_get_array_value() and its variants is 0 on success
 or negative on error. Note the difference to gpiod_get_value(), which returns
 0 or 1 on success to convey the GPIO value. With the array functions, the GPIO
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 4d26cdbdb7cf..b799a89c4c17 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2787,7 +2787,36 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
 				  struct gpio_array *array_info,
 				  unsigned long *value_bitmap)
 {
-	int i = 0;
+	int err, i = 0;
+
+	/*
+	 * Validate array_info against desc_array and its size.
+	 * It should immediately follow desc_array if both
+	 * have been obtained from the same gpiod_get_array() call.
+	 */
+	if (array_info && array_info->desc == desc_array &&
+	    array_size <= array_info->size &&
+	    (void *)array_info == desc_array + array_info->size) {
+		if (!can_sleep)
+			WARN_ON(array_info->chip->can_sleep);
+
+		err = gpio_chip_get_multiple(array_info->chip,
+					     array_info->get_mask,
+					     value_bitmap);
+		if (err)
+			return err;
+
+		if (!raw && !bitmap_empty(array_info->invert_mask, array_size))
+			bitmap_xor(value_bitmap, value_bitmap,
+				   array_info->invert_mask, array_size);
+
+		if (bitmap_full(array_info->get_mask, array_size))
+			return 0;
+
+		i = find_first_zero_bit(array_info->get_mask, array_size);
+	} else {
+		array_info = NULL;
+	}
 
 	while (i < array_size) {
 		struct gpio_chip *chip = desc_array[i]->gdev->chip;
@@ -2818,7 +2847,12 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
 			int hwgpio = gpio_chip_hwgpio(desc);
 
 			__set_bit(hwgpio, mask);
-			i++;
+
+			if (array_info)
+				find_next_zero_bit(array_info->get_mask,
+						   array_size, i);
+			else
+				i++;
 		} while ((i < array_size) &&
 			 (desc_array[i]->gdev->chip == chip));
 
@@ -2829,7 +2863,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
 			return ret;
 		}
 
-		for (j = first; j < i; j++) {
+		for (j = first; j < i; ) {
 			const struct gpio_desc *desc = desc_array[j];
 			int hwgpio = gpio_chip_hwgpio(desc);
 			int value = test_bit(hwgpio, bits);
@@ -2838,6 +2872,11 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
 				value = !value;
 			__assign_bit(j, value_bitmap, value);
 			trace_gpio_value(desc_to_gpio(desc), 1, value);
+
+			if (array_info)
+				find_next_zero_bit(array_info->get_mask, i, j);
+			else
+				j++;
 		}
 
 		if (mask != fastpath)
@@ -3039,6 +3078,32 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
 {
 	int i = 0;
 
+	/*
+	 * Validate array_info against desc_array and its size.
+	 * It should immediately follow desc_array if both
+	 * have been obtained from the same gpiod_get_array() call.
+	 */
+	if (array_info && array_info->desc == desc_array &&
+	    array_size <= array_info->size &&
+	    (void *)array_info == desc_array + array_info->size) {
+		if (!can_sleep)
+			WARN_ON(array_info->chip->can_sleep);
+
+		if (!raw && !bitmap_empty(array_info->invert_mask, array_size))
+			bitmap_xor(value_bitmap, value_bitmap,
+				   array_info->invert_mask, array_size);
+
+		gpio_chip_set_multiple(array_info->chip, array_info->set_mask,
+				       value_bitmap);
+
+		if (bitmap_full(array_info->set_mask, array_size))
+			return 0;
+
+		i = find_first_zero_bit(array_info->set_mask, array_size);
+	} else {
+		array_info = NULL;
+	}
+
 	while (i < array_size) {
 		struct gpio_chip *chip = desc_array[i]->gdev->chip;
 		unsigned long fastpath[2 * BITS_TO_LONGS(FASTPATH_NGPIO)];
@@ -3066,7 +3131,14 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
 			int hwgpio = gpio_chip_hwgpio(desc);
 			int value = test_bit(i, value_bitmap);
 
-			if (!raw && test_bit(FLAG_ACTIVE_LOW, &desc->flags))
+			/*
+			 * Pins applicable for fast input but not for
+			 * fast output processing may have been already
+			 * inverted inside the fast path, skip them.
+			 */
+			if (!raw && !(array_info &&
+			    test_bit(i, array_info->invert_mask)) &&
+			    test_bit(FLAG_ACTIVE_LOW, &desc->flags))
 				value = !value;
 			trace_gpio_value(desc_to_gpio(desc), 0, value);
 			/*
@@ -3085,7 +3157,12 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
 					__clear_bit(hwgpio, bits);
 				count++;
 			}
-			i++;
+
+			if (array_info)
+				find_next_zero_bit(array_info->set_mask,
+						   array_size, i);
+			else
+				i++;
 		} while ((i < array_size) &&
 			 (desc_array[i]->gdev->chip == chip));
 		/* push collected bits to outputs */
-- 
2.16.4

^ permalink raw reply related

* [RFC RFT PATCH v4 3/4] gpiolib: Pass array info to get/set array functions
From: Janusz Krzysztofik @ 2018-08-20 23:43 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Andrew Lunn, Ulf Hansson, linux-doc, linux-iio, Dominik Brodowski,
	netdev, linux-i2c, Peter Meerwald-Stadler, devel,
	Florian Fainelli, Jonathan Corbet, Janusz Krzysztofik,
	Kishon Vijay Abraham I, linux-serial, Jiri Slaby,
	Michael Hennerich, linux-gpio, Lars-Peter Clausen,
	Greg Kroah-Hartman, linux-mmc, linux-kernel, Peter Rosin,
	Miguel Ojeda Sandonis, Peter Korsgaard, Hartmut Knaack <kna
In-Reply-To: <20180820234341.5271-1-jmkrzyszt@gmail.com>

In order to make use of array info obtained from gpiod_get_array() and
speed up processing of arrays matching single GPIO chip layout, that
information must be passed to get/set array functions.  Extend the
functions' API with that additional parameter and update all users.
Pass NULL if a user bulids an array itself from single GPIOs.

Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
---
 Documentation/driver-api/gpio/consumer.rst  | 14 ++++++++++--
 drivers/auxdisplay/hd44780.c                | 12 ++++++----
 drivers/bus/ts-nbus.c                       |  6 +++--
 drivers/gpio/gpio-max3191x.c                |  6 +++--
 drivers/gpio/gpiolib.c                      | 34 ++++++++++++++++++++---------
 drivers/gpio/gpiolib.h                      |  2 ++
 drivers/i2c/muxes/i2c-mux-gpio.c            |  2 +-
 drivers/mmc/core/pwrseq_simple.c            |  2 +-
 drivers/mux/gpio.c                          |  3 ++-
 drivers/net/phy/mdio-mux-gpio.c             |  2 +-
 drivers/pcmcia/soc_common.c                 |  3 ++-
 drivers/phy/motorola/phy-mapphone-mdm6600.c |  4 +++-
 drivers/staging/iio/adc/ad7606.c            |  3 ++-
 drivers/tty/serial/serial_mctrl_gpio.c      |  2 +-
 include/linux/gpio/consumer.h               |  8 +++++++
 15 files changed, 75 insertions(+), 28 deletions(-)

diff --git a/Documentation/driver-api/gpio/consumer.rst b/Documentation/driver-api/gpio/consumer.rst
index 7e0298b9a7b9..0afd95a12b10 100644
--- a/Documentation/driver-api/gpio/consumer.rst
+++ b/Documentation/driver-api/gpio/consumer.rst
@@ -325,28 +325,36 @@ The following functions get or set the values of an array of GPIOs::
 
 	int gpiod_get_array_value(unsigned int array_size,
 				  struct gpio_desc **desc_array,
+				  struct gpio_array *array_info,
 				  unsigned long *value_bitmap);
 	int gpiod_get_raw_array_value(unsigned int array_size,
 				      struct gpio_desc **desc_array,
+				      struct gpio_array *array_info,
 				      unsigned long *value_bitmap);
 	int gpiod_get_array_value_cansleep(unsigned int array_size,
 					   struct gpio_desc **desc_array,
+					   struct gpio_array *array_info,
 					   unsigned long *value_bitmap);
 	int gpiod_get_raw_array_value_cansleep(unsigned int array_size,
 					   struct gpio_desc **desc_array,
+					   struct gpio_array *array_info,
 					   unsigned long *value_bitmap);
 
 	void gpiod_set_array_value(unsigned int array_size,
 				   struct gpio_desc **desc_array,
+				   struct gpio_array *array_info,
 				   unsigned long *value_bitmap)
 	void gpiod_set_raw_array_value(unsigned int array_size,
 				       struct gpio_desc **desc_array,
+				       struct gpio_array *array_info,
 				       unsigned long *value_bitmap)
 	void gpiod_set_array_value_cansleep(unsigned int array_size,
 					    struct gpio_desc **desc_array,
+					    struct gpio_array *array_info,
 					    unsigned long *value_bitmap)
 	void gpiod_set_raw_array_value_cansleep(unsigned int array_size,
 						struct gpio_desc **desc_array,
+						struct gpio_array *array_info,
 						unsigned long *value_bitmap)
 
 The array can be an arbitrary set of GPIOs. The functions will try to access
@@ -358,6 +366,7 @@ accessed sequentially.
 The functions take three arguments:
 	* array_size	- the number of array elements
 	* desc_array	- an array of GPIO descriptors
+	* array_info	- optional information obtained from gpiod_array_get()
 	* value_bitmap	- a bitmap to store the GPIOs' values (get) or
 			  a bitmap of values to assign to the GPIOs (set)
 
@@ -368,12 +377,13 @@ the struct gpio_descs returned by gpiod_get_array()::
 
 	struct gpio_descs *my_gpio_descs = gpiod_get_array(...);
 	gpiod_set_array_value(my_gpio_descs->ndescs, my_gpio_descs->desc,
-			      my_gpio_value_bitmap);
+			      my_gpio_descs->info, my_gpio_value_bitmap);
 
 It is also possible to access a completely arbitrary array of descriptors. The
 descriptors may be obtained using any combination of gpiod_get() and
 gpiod_get_array(). Afterwards the array of descriptors has to be setup
-manually before it can be passed to one of the above functions.
+manually before it can be passed to one of the above functions.  In that case,
+array_info should be set to NULL.
 
 Note that for optimal performance GPIOs belonging to the same chip should be
 contiguous within the array of descriptors.
diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c
index d340473aa142..6ae81632bc44 100644
--- a/drivers/auxdisplay/hd44780.c
+++ b/drivers/auxdisplay/hd44780.c
@@ -74,7 +74,8 @@ static void hd44780_write_gpio8(struct hd44780 *hd, u8 val, unsigned int rs)
 	}
 
 	/* Present the data to the port */
-	gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA0], value_bitmap);
+	gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA0], NULL,
+				       value_bitmap);
 
 	hd44780_strobe_gpio(hd);
 }
@@ -97,7 +98,8 @@ static void hd44780_write_gpio4(struct hd44780 *hd, u8 val, unsigned int rs)
 	value_bitmap[0] = value_bitmap[0] >> PIN_DATA4;
 
 	/* Present the data to the port */
-	gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], value_bitmap);
+	gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], NULL,
+				       value_bitmap);
 
 	hd44780_strobe_gpio(hd);
 
@@ -106,7 +108,8 @@ static void hd44780_write_gpio4(struct hd44780 *hd, u8 val, unsigned int rs)
 	value_bitmap[0] |= val & ~((1 << PIN_DATA4) - 1);
 
 	/* Present the data to the port */
-	gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], value_bitmap);
+	gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], NULL,
+				       value_bitmap);
 
 	hd44780_strobe_gpio(hd);
 }
@@ -169,7 +172,8 @@ static void hd44780_write_cmd_raw_gpio4(struct charlcd *lcd, int cmd)
 	value_bitmap[0] = value_bitmap[0] >> PIN_DATA4;
 
 	/* Present the data to the port */
-	gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], value_bitmap);
+	gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], NULL,
+				       value_bitmap);
 
 	hd44780_strobe_gpio(hd);
 }
diff --git a/drivers/bus/ts-nbus.c b/drivers/bus/ts-nbus.c
index ce6c1e89236d..000d756eb42c 100644
--- a/drivers/bus/ts-nbus.c
+++ b/drivers/bus/ts-nbus.c
@@ -112,7 +112,8 @@ static void ts_nbus_reset_bus(struct ts_nbus *ts_nbus)
 {
 	unsigned long value_bitmap[1] = { 0, };
 
-	gpiod_set_array_value_cansleep(8, ts_nbus->data->desc, value_bitmap);
+	gpiod_set_array_value_cansleep(8, ts_nbus->data->desc,
+				       ts_nbus->data->info, value_bitmap);
 	gpiod_set_value_cansleep(ts_nbus->csn, 0);
 	gpiod_set_value_cansleep(ts_nbus->strobe, 0);
 	gpiod_set_value_cansleep(ts_nbus->ale, 0);
@@ -155,7 +156,8 @@ static void ts_nbus_write_byte(struct ts_nbus *ts_nbus, u8 byte)
 	struct gpio_descs *gpios = ts_nbus->data;
 	unsigned long value_bitmap[1] = { byte, };
 
-	gpiod_set_array_value_cansleep(8, gpios->desc, value_bitmap);
+	gpiod_set_array_value_cansleep(8, gpios->desc, gpios->info,
+				       value_bitmap);
 }
 
 /*
diff --git a/drivers/gpio/gpio-max3191x.c b/drivers/gpio/gpio-max3191x.c
index c4ec1c82af27..4b43b5dabfd2 100644
--- a/drivers/gpio/gpio-max3191x.c
+++ b/drivers/gpio/gpio-max3191x.c
@@ -313,6 +313,7 @@ static int max3191x_set_config(struct gpio_chip *gpio, unsigned int offset,
 
 static void gpiod_set_array_single_value_cansleep(unsigned int ndescs,
 						  struct gpio_desc **desc,
+						  struct gpio_array *info,
 						  int value)
 {
 	unsigned long *value_bitmap;
@@ -327,7 +328,7 @@ static void gpiod_set_array_single_value_cansleep(unsigned int ndescs,
 	else
 		bitmap_zero(value_bitmap, ndescs);
 
-	gpiod_set_array_value_cansleep(ndescs, desc, value_bitmap);
+	gpiod_set_array_value_cansleep(ndescs, desc, info, value_bitmap);
 	kfree(value_bitmap);
 }
 
@@ -400,7 +401,8 @@ static int max3191x_probe(struct spi_device *spi)
 	if (max3191x->modesel_pins)
 		gpiod_set_array_single_value_cansleep(
 				 max3191x->modesel_pins->ndescs,
-				 max3191x->modesel_pins->desc, max3191x->mode);
+				 max3191x->modesel_pins->desc,
+				 max3191x->modesel_pins->info, max3191x->mode);
 
 	max3191x->ignore_uv = device_property_read_bool(dev,
 						  "maxim,ignore-undervoltage");
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index c1ed1c759345..4d26cdbdb7cf 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -435,7 +435,7 @@ static long linehandle_ioctl(struct file *filep, unsigned int cmd,
 		int ret = gpiod_get_array_value_complex(false,
 							true,
 							lh->numdescs,
-							lh->descs,
+							lh->descs, NULL,
 							value_bitmap);
 		if (ret)
 			return ret;
@@ -467,7 +467,7 @@ static long linehandle_ioctl(struct file *filep, unsigned int cmd,
 		return gpiod_set_array_value_complex(false,
 					      true,
 					      lh->numdescs,
-					      lh->descs,
+					      lh->descs, NULL,
 					      value_bitmap);
 	}
 	return -EINVAL;
@@ -2784,6 +2784,7 @@ static int gpio_chip_get_multiple(struct gpio_chip *chip,
 int gpiod_get_array_value_complex(bool raw, bool can_sleep,
 				  unsigned int array_size,
 				  struct gpio_desc **desc_array,
+				  struct gpio_array *array_info,
 				  unsigned long *value_bitmap)
 {
 	int i = 0;
@@ -2908,12 +2909,14 @@ EXPORT_SYMBOL_GPL(gpiod_get_value);
  */
 int gpiod_get_raw_array_value(unsigned int array_size,
 			      struct gpio_desc **desc_array,
+			      struct gpio_array *array_info,
 			      unsigned long *value_bitmap)
 {
 	if (!desc_array)
 		return -EINVAL;
 	return gpiod_get_array_value_complex(true, false, array_size,
-					     desc_array, value_bitmap);
+					     desc_array, array_info,
+					     value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_get_raw_array_value);
 
@@ -2931,12 +2934,14 @@ EXPORT_SYMBOL_GPL(gpiod_get_raw_array_value);
  */
 int gpiod_get_array_value(unsigned int array_size,
 			  struct gpio_desc **desc_array,
+			  struct gpio_array *array_info,
 			  unsigned long *value_bitmap)
 {
 	if (!desc_array)
 		return -EINVAL;
 	return gpiod_get_array_value_complex(false, false, array_size,
-					     desc_array, value_bitmap);
+					     desc_array, array_info,
+					     value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_get_array_value);
 
@@ -3029,6 +3034,7 @@ static void gpio_chip_set_multiple(struct gpio_chip *chip,
 int gpiod_set_array_value_complex(bool raw, bool can_sleep,
 				   unsigned int array_size,
 				   struct gpio_desc **desc_array,
+				   struct gpio_array *array_info,
 				   unsigned long *value_bitmap)
 {
 	int i = 0;
@@ -3166,12 +3172,13 @@ EXPORT_SYMBOL_GPL(gpiod_set_value);
  */
 int gpiod_set_raw_array_value(unsigned int array_size,
 			 struct gpio_desc **desc_array,
+			 struct gpio_array *array_info,
 			 unsigned long *value_bitmap)
 {
 	if (!desc_array)
 		return -EINVAL;
 	return gpiod_set_array_value_complex(true, false, array_size,
-					desc_array, value_bitmap);
+					desc_array, array_info, value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_set_raw_array_value);
 
@@ -3189,12 +3196,13 @@ EXPORT_SYMBOL_GPL(gpiod_set_raw_array_value);
  */
 void gpiod_set_array_value(unsigned int array_size,
 			   struct gpio_desc **desc_array,
+			   struct gpio_array *array_info,
 			   unsigned long *value_bitmap)
 {
 	if (!desc_array)
 		return;
 	gpiod_set_array_value_complex(false, false, array_size, desc_array,
-				      value_bitmap);
+				      array_info, value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_set_array_value);
 
@@ -3426,13 +3434,15 @@ EXPORT_SYMBOL_GPL(gpiod_get_value_cansleep);
  */
 int gpiod_get_raw_array_value_cansleep(unsigned int array_size,
 				       struct gpio_desc **desc_array,
+				       struct gpio_array *array_info,
 				       unsigned long *value_bitmap)
 {
 	might_sleep_if(extra_checks);
 	if (!desc_array)
 		return -EINVAL;
 	return gpiod_get_array_value_complex(true, true, array_size,
-					     desc_array, value_bitmap);
+					     desc_array, array_info,
+					     value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_get_raw_array_value_cansleep);
 
@@ -3449,13 +3459,15 @@ EXPORT_SYMBOL_GPL(gpiod_get_raw_array_value_cansleep);
  */
 int gpiod_get_array_value_cansleep(unsigned int array_size,
 				   struct gpio_desc **desc_array,
+				   struct gpio_array *array_info,
 				   unsigned long *value_bitmap)
 {
 	might_sleep_if(extra_checks);
 	if (!desc_array)
 		return -EINVAL;
 	return gpiod_get_array_value_complex(false, true, array_size,
-					     desc_array, value_bitmap);
+					     desc_array, array_info,
+					     value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_get_array_value_cansleep);
 
@@ -3508,13 +3520,14 @@ EXPORT_SYMBOL_GPL(gpiod_set_value_cansleep);
  */
 int gpiod_set_raw_array_value_cansleep(unsigned int array_size,
 					struct gpio_desc **desc_array,
+					struct gpio_array *array_info,
 					unsigned long *value_bitmap)
 {
 	might_sleep_if(extra_checks);
 	if (!desc_array)
 		return -EINVAL;
 	return gpiod_set_array_value_complex(true, true, array_size, desc_array,
-				      value_bitmap);
+				      array_info, value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_set_raw_array_value_cansleep);
 
@@ -3548,13 +3561,14 @@ void gpiod_add_lookup_tables(struct gpiod_lookup_table **tables, size_t n)
  */
 void gpiod_set_array_value_cansleep(unsigned int array_size,
 				    struct gpio_desc **desc_array,
+				    struct gpio_array *array_info,
 				    unsigned long *value_bitmap)
 {
 	might_sleep_if(extra_checks);
 	if (!desc_array)
 		return;
 	gpiod_set_array_value_complex(false, true, array_size, desc_array,
-				      value_bitmap);
+				      array_info, value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_set_array_value_cansleep);
 
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index b60905d558b1..b65ca896b24d 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -196,10 +196,12 @@ struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, u16 hwnum);
 int gpiod_get_array_value_complex(bool raw, bool can_sleep,
 				  unsigned int array_size,
 				  struct gpio_desc **desc_array,
+				  struct gpio_array *array_info,
 				  unsigned long *value_bitmap);
 int gpiod_set_array_value_complex(bool raw, bool can_sleep,
 				   unsigned int array_size,
 				   struct gpio_desc **desc_array,
+				   struct gpio_array *array_info,
 				   unsigned long *value_bitmap);
 
 /* This is just passed between gpiolib and devres */
diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
index d675e0ca2fa4..aa3857ab42b5 100644
--- a/drivers/i2c/muxes/i2c-mux-gpio.c
+++ b/drivers/i2c/muxes/i2c-mux-gpio.c
@@ -34,7 +34,7 @@ static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
 		mux->values[i] = (val >> i) & 1;
 
 	gpiod_set_array_value_cansleep(mux->data.n_gpios,
-				       mux->gpios, value_bitmap);
+				       mux->gpios, NULL, value_bitmap);
 }
 
 static int i2c_mux_gpio_select(struct i2c_mux_core *muxc, u32 chan)
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index 0d6e3a5be3ba..5cf7eda8f68f 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -46,7 +46,7 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,
 		value_bitmap[0] = value;
 
 		gpiod_set_array_value_cansleep(nvalues, reset_gpios->desc,
-					       value_bitmap);
+					       reset_gpios->info, value_bitmap);
 	}
 }
 
diff --git a/drivers/mux/gpio.c b/drivers/mux/gpio.c
index cc2d5f50472a..879f9f3f45dd 100644
--- a/drivers/mux/gpio.c
+++ b/drivers/mux/gpio.c
@@ -30,7 +30,8 @@ static int mux_gpio_set(struct mux_control *mux, int state)
 		mux_gpio->val[i] = (state >> i) & 1;
 
 	gpiod_set_array_value_cansleep(mux_gpio->gpios->ndescs,
-				       mux_gpio->gpios->desc, value_bitmap);
+				       mux_gpio->gpios->desc,
+				       mux_gpio->gpios->info, value_bitmap);
 
 	return 0;
 }
diff --git a/drivers/net/phy/mdio-mux-gpio.c b/drivers/net/phy/mdio-mux-gpio.c
index 8e1ec750277e..c0ffa03c916b 100644
--- a/drivers/net/phy/mdio-mux-gpio.c
+++ b/drivers/net/phy/mdio-mux-gpio.c
@@ -37,7 +37,7 @@ static int mdio_mux_gpio_switch_fn(int current_child, int desired_child,
 		s->values[n] = (desired_child >> n) & 1;
 
 	gpiod_set_array_value_cansleep(s->gpios->ndescs, s->gpios->desc,
-				       value_bitmap);
+				       s->gpios->info, value_bitmap);
 
 	return 0;
 }
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index e0f89155c474..55978198cd2b 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -366,7 +366,8 @@ static int soc_common_pcmcia_config_skt(
 		}
 
 		if (n)
-			gpiod_set_array_value_cansleep(n, descs, value_bitmap);
+			gpiod_set_array_value_cansleep(n, descs, NULL,
+						       value_bitmap);
 
 		/*
 		 * This really needs a better solution.  The IRQ
diff --git a/drivers/phy/motorola/phy-mapphone-mdm6600.c b/drivers/phy/motorola/phy-mapphone-mdm6600.c
index b6477c3599c4..8f508338ec56 100644
--- a/drivers/phy/motorola/phy-mapphone-mdm6600.c
+++ b/drivers/phy/motorola/phy-mapphone-mdm6600.c
@@ -162,7 +162,8 @@ static void phy_mdm6600_cmd(struct phy_mdm6600 *ddata, int val)
 	value_bitmap[0] = val & ((1 << PHY_MDM6600_NR_CMD_LINES) - 1);
 
 	gpiod_set_array_value_cansleep(PHY_MDM6600_NR_CMD_LINES,
-				       ddata->cmd_gpios->desc, value_bitmap);
+				       ddata->cmd_gpios->desc,
+				       ddata->cmd_gpios->info, value_bitmap);
 }
 
 /**
@@ -181,6 +182,7 @@ static void phy_mdm6600_status(struct work_struct *work)
 
 	error = gpiod_get_array_value_cansleep(PHY_MDM6600_NR_STATUS_LINES,
 					       ddata->status_gpios->desc,
+					       ddata->status_gpios->info,
 					       value_bitmap);
 	if (error)
 		return;
diff --git a/drivers/staging/iio/adc/ad7606.c b/drivers/staging/iio/adc/ad7606.c
index 0eca047bc1cc..eb779d825724 100644
--- a/drivers/staging/iio/adc/ad7606.c
+++ b/drivers/staging/iio/adc/ad7606.c
@@ -230,7 +230,8 @@ static int ad7606_write_raw(struct iio_dev *indio_dev,
 		value_bitmap[0] = ret;
 
 		mutex_lock(&st->lock);
-		gpiod_set_array_value(3, st->gpio_os->desc, value_bitmap);
+		gpiod_set_array_value(3, st->gpio_os->desc, st->gpio_os->info,
+				      value_bitmap);
 		st->oversampling = val;
 		mutex_unlock(&st->lock);
 
diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c
index bb8b4756d72d..8a04e3be5419 100644
--- a/drivers/tty/serial/serial_mctrl_gpio.c
+++ b/drivers/tty/serial/serial_mctrl_gpio.c
@@ -53,7 +53,7 @@ void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl)
 				     !!(mctrl & mctrl_gpios_desc[i].mctrl));
 			count++;
 		}
-	gpiod_set_array_value(count, desc_array, value_bitmap);
+	gpiod_set_array_value(count, desc_array, NULL, value_bitmap);
 }
 EXPORT_SYMBOL_GPL(mctrl_gpio_set);
 
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index 8dede3e886af..bf037ebe2ed8 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -114,36 +114,44 @@ int gpiod_direction_output_raw(struct gpio_desc *desc, int value);
 int gpiod_get_value(const struct gpio_desc *desc);
 int gpiod_get_array_value(unsigned int array_size,
 			  struct gpio_desc **desc_array,
+			  struct gpio_array *array_info,
 			  unsigned long *value_bitmap);
 void gpiod_set_value(struct gpio_desc *desc, int value);
 void gpiod_set_array_value(unsigned int array_size,
 			   struct gpio_desc **desc_array,
+			   struct gpio_array *array_info,
 			   unsigned long *value_bitmap);
 int gpiod_get_raw_value(const struct gpio_desc *desc);
 int gpiod_get_raw_array_value(unsigned int array_size,
 			      struct gpio_desc **desc_array,
+			      struct gpio_array *array_info,
 			      unsigned long *value_bitmap);
 void gpiod_set_raw_value(struct gpio_desc *desc, int value);
 int gpiod_set_raw_array_value(unsigned int array_size,
 			       struct gpio_desc **desc_array,
+			       struct gpio_array *array_info,
 			       unsigned long *value_bitmap);
 
 /* Value get/set from sleeping context */
 int gpiod_get_value_cansleep(const struct gpio_desc *desc);
 int gpiod_get_array_value_cansleep(unsigned int array_size,
 				   struct gpio_desc **desc_array,
+				   struct gpio_array *array_info,
 				   unsigned long *value_bitmap);
 void gpiod_set_value_cansleep(struct gpio_desc *desc, int value);
 void gpiod_set_array_value_cansleep(unsigned int array_size,
 				    struct gpio_desc **desc_array,
+				    struct gpio_array *array_info,
 				    unsigned long *value_bitmap);
 int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc);
 int gpiod_get_raw_array_value_cansleep(unsigned int array_size,
 				       struct gpio_desc **desc_array,
+				       struct gpio_array *array_info,
 				       unsigned long *value_bitmap);
 void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value);
 int gpiod_set_raw_array_value_cansleep(unsigned int array_size,
 					struct gpio_desc **desc_array,
+					struct gpio_array *array_info,
 					unsigned long *value_bitmap);
 
 int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce);
-- 
2.16.4

^ permalink raw reply related

* [RFC RFT PATCH v4 2/4] gpiolib: Identify arrays matching GPIO hardware
From: Janusz Krzysztofik @ 2018-08-20 23:43 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Andrew Lunn, Ulf Hansson, linux-doc, linux-iio, Dominik Brodowski,
	netdev, linux-i2c, Peter Meerwald-Stadler, devel,
	Florian Fainelli, Jonathan Corbet, Janusz Krzysztofik,
	Kishon Vijay Abraham I, linux-serial, Jiri Slaby,
	Michael Hennerich, linux-gpio, Lars-Peter Clausen,
	Greg Kroah-Hartman, linux-mmc, linux-kernel, Peter Rosin,
	Miguel Ojeda Sandonis, Peter Korsgaard, Hartmut Knaack <kna
In-Reply-To: <20180820234341.5271-1-jmkrzyszt@gmail.com>

Certain GPIO array lookup results may map directly to GPIO pins of a
single GPIO chip in hardware order.  If that condition is recognized
and handled efficiently, significant performance gain of get/set array
functions may be possible.

While processing a request for an array of GPIO descriptors, identify
those which represent corresponding pins of a single GPIO chip.  Skip
over pins which require open source or open drain special processing.
Moreover, identify pins which require inversion.  Pass a pointer to
that information with the array to the caller so it can benefit from
enhanced performance as soon as get/set array functions can accept and
make efficient use of it.

Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
---
 Documentation/driver-api/gpio/consumer.rst |  4 +-
 drivers/gpio/gpiolib.c                     | 72 +++++++++++++++++++++++++++++-
 drivers/gpio/gpiolib.h                     |  9 ++++
 include/linux/gpio/consumer.h              |  9 ++++
 4 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/Documentation/driver-api/gpio/consumer.rst b/Documentation/driver-api/gpio/consumer.rst
index ed68042ddccf..7e0298b9a7b9 100644
--- a/Documentation/driver-api/gpio/consumer.rst
+++ b/Documentation/driver-api/gpio/consumer.rst
@@ -109,9 +109,11 @@ For a function using multiple GPIOs all of those can be obtained with one call::
 					   enum gpiod_flags flags)
 
 This function returns a struct gpio_descs which contains an array of
-descriptors::
+descriptors.  It also contains a pointer to a gpiolib private structure which,
+if passed back to get/set array functions, may speed up I/O proocessing::
 
 	struct gpio_descs {
+		struct gpio_array *info;
 		unsigned int ndescs;
 		struct gpio_desc *desc[];
 	}
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index f0e9ffa8cab6..c1ed1c759345 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -4174,7 +4174,9 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
 {
 	struct gpio_desc *desc;
 	struct gpio_descs *descs;
-	int count;
+	struct gpio_array *array_info = NULL;
+	struct gpio_chip *chip;
+	int count, bitmap_size;
 
 	count = gpiod_count(dev, con_id);
 	if (count < 0)
@@ -4190,9 +4192,77 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
 			gpiod_put_array(descs);
 			return ERR_CAST(desc);
 		}
+
 		descs->desc[descs->ndescs] = desc;
+
+		chip = gpiod_to_chip(desc);
+		/*
+		 * Select a chip of first array member
+		 * whose index matches its pin hardware number
+		 * as a candidate for fast bitmap processing.
+		 */
+		if (!array_info && gpio_chip_hwgpio(desc) == descs->ndescs) {
+			struct gpio_descs *array;
+
+			bitmap_size = BITS_TO_LONGS(chip->ngpio > count ?
+						    chip->ngpio : count);
+
+			array = kzalloc(struct_size(descs, desc, count) +
+					struct_size(array_info, invert_mask,
+					3 * bitmap_size), GFP_KERNEL);
+			if (!array) {
+				gpiod_put_array(descs);
+				return ERR_PTR(-ENOMEM);
+			}
+
+			memcpy(array, descs,
+			       struct_size(descs, desc, descs->ndescs + 1));
+			kfree(descs);
+
+			descs = array;
+			array_info = (void *)(descs->desc + count);
+			array_info->get_mask = array_info->invert_mask +
+						  bitmap_size;
+			array_info->set_mask = array_info->get_mask +
+						  bitmap_size;
+
+			array_info->desc = descs->desc;
+			array_info->size = count;
+			array_info->chip = chip;
+			bitmap_set(array_info->get_mask, descs->ndescs,
+				   count - descs->ndescs);
+			bitmap_set(array_info->set_mask, descs->ndescs,
+				   count - descs->ndescs);
+			descs->info = array_info;
+		}
+		/*
+		 * Unmark members which don't qualify for fast bitmap
+		 * processing (different chip, not in hardware order)
+		 */
+		if (array_info && (chip != array_info->chip ||
+		    gpio_chip_hwgpio(desc) != descs->ndescs)) {
+			__clear_bit(descs->ndescs, array_info->get_mask);
+			__clear_bit(descs->ndescs, array_info->set_mask);
+		} else if (array_info) {
+			/* Exclude open drain or open source from fast output */
+			if (gpiochip_line_is_open_drain(chip, descs->ndescs) ||
+			    gpiochip_line_is_open_source(chip, descs->ndescs))
+				__clear_bit(descs->ndescs,
+					    array_info->set_mask);
+			/* Identify 'fast' pins which require invertion */
+			if (gpiod_is_active_low(desc))
+				__set_bit(descs->ndescs,
+					  array_info->invert_mask);
+		}
+
 		descs->ndescs++;
 	}
+	if (array_info)
+		dev_dbg(dev,
+			"GPIO array info: chip=%s, size=%d, get_mask=%lx, set_mask=%lx, invert_mask=%lx\n",
+			array_info->chip->label, array_info->size,
+			*array_info->get_mask, *array_info->set_mask,
+			*array_info->invert_mask);
 	return descs;
 }
 EXPORT_SYMBOL_GPL(gpiod_get_array);
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 11e83d2eef89..b60905d558b1 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -183,6 +183,15 @@ static inline bool acpi_can_fallback_to_crs(struct acpi_device *adev,
 }
 #endif
 
+struct gpio_array {
+	struct gpio_desc	**desc;
+	unsigned int		size;
+	struct gpio_chip	*chip;
+	unsigned long		*get_mask;
+	unsigned long		*set_mask;
+	unsigned long		invert_mask[];
+};
+
 struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, u16 hwnum);
 int gpiod_get_array_value_complex(bool raw, bool can_sleep,
 				  unsigned int array_size,
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index 1b21dc7b0fad..8dede3e886af 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -17,11 +17,20 @@ struct device;
  */
 struct gpio_desc;
 
+/**
+ * Opaque descriptor for a structure of GPIO array attributes.  This structure
+ * is attached to struct gpiod_descs obtained from gpiod_get_array() and can be
+ * passed back to get/set array functions in order to activate fast processing
+ * path if applicable.
+ */
+struct gpio_array;
+
 /**
  * Struct containing an array of descriptors that can be obtained using
  * gpiod_get_array().
  */
 struct gpio_descs {
+	struct gpio_array *info;
 	unsigned int ndescs;
 	struct gpio_desc *desc[];
 };
-- 
2.16.4

^ permalink raw reply related

* [RFC RFT PATCH 0/4] gpiolib: speed up GPIO array processing
From: Janusz Krzysztofik @ 2018-08-20 23:43 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Andrew Lunn, Ulf Hansson, linux-doc, linux-iio, Dominik Brodowski,
	netdev, linux-i2c, Peter Meerwald-Stadler, devel,
	Florian Fainelli, Jonathan Corbet, Janusz Krzysztofik,
	Kishon Vijay Abraham I, linux-serial, Jiri Slaby,
	Michael Hennerich, linux-gpio, Lars-Peter Clausen,
	Greg Kroah-Hartman, linux-mmc, linux-kernel, Peter Rosin,
	Miguel Ojeda Sandonis, Peter Korsgaard, Hartmut Knaack <kna
In-Reply-To: <20180813223448.21316-1-jmkrzyszt@gmail.com>


This series is a follow up of the former "mtd: rawnand: ams-delta: Use
gpio-omap accessors for data I/O" which already contained some changes
to gpiolib.  Those previous attempts were commented by Borris Brezillon
who suggested using GPIO API modified to accept bitmaps, and by Linus
Walleij who suggested still more great ideas for further immprovement
of the proposed API changes - thanks!

The goal is to boost performans of get/set array functions while
processing GPIO arrays which represent pins of a signle chip in
hardware order.  If resulting performance is close to PIO, GPIO API
can be used for data I/O without much loss of speed.

Created and tested on a low end Amstrad Delta board with NAND driver
updated to use GPIO API for data I/O.  Performance degrade compared to
PIO is much better than before the optimization but still not quite
satisfactory.


Janusz Krzysztofik (4):
      gpiolib: Pass bitmaps, not integer arrays, to get/set array
      gpiolib: Identify arrays matching GPIO hardware
      gpiolib: Pass array info to get/set array functions
      gpiolib: Implement fast processing path in get/set array


 Documentation/driver-api/gpio/board.rst     |   15 +
 Documentation/driver-api/gpio/consumer.rst  |   48 +++-
 drivers/auxdisplay/hd44780.c                |   64 +++---
 drivers/bus/ts-nbus.c                       |   25 --
 drivers/gpio/gpio-max3191x.c                |   23 +-
 drivers/gpio/gpiolib.c                      |  279 ++++++++++++++++++++++------
 drivers/gpio/gpiolib.h                      |   15 +
 drivers/i2c/muxes/i2c-mux-gpio.c            |    5 
 drivers/mmc/core/pwrseq_simple.c            |   15 -
 drivers/mux/gpio.c                          |    7 
 drivers/net/phy/mdio-mux-gpio.c             |    5 
 drivers/pcmcia/soc_common.c                 |   14 -
 drivers/phy/motorola/phy-mapphone-mdm6600.c |   21 +-
 drivers/staging/iio/adc/ad7606.c            |   12 -
 drivers/tty/serial/serial_mctrl_gpio.c      |    9 
 include/linux/gpio/consumer.h               |   35 ++-
 16 files changed, 410 insertions(+), 182 deletions(-)

^ permalink raw reply

* Re: Checkpatch False positive
From: Matthew Wilcox @ 2018-08-20 20:22 UTC (permalink / raw)
  To: Jeff Kirsher; +Cc: Andy Whitcroft, Joe Perches, netdev, Linux Docs
In-Reply-To: <8cf91e5fb848eecd98a2f9493387906b3a5f1506.camel@intel.com>

On Mon, Aug 20, 2018 at 01:21:30PM -0700, Jeff Kirsher wrote:
> Checkpatch.pl should probably exclude *.rst files from the SPDX License
> Identifier check, since they are documentational files, like *.txt. 

They're still copyrighted work, so they should still have SPDX tags
to identify their license.

checkpatch has:

                                } elsif ($realfile =~ /\.rst$/) {
                                        $comment = '..';

so we're explicitly including rst files in the checking for now.

^ permalink raw reply

* Checkpatch False positive
From: Jeff Kirsher @ 2018-08-20 20:21 UTC (permalink / raw)
  To: Andy Whitcroft, Joe Perches; +Cc: netdev, Linux Docs

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

Checkpatch.pl should probably exclude *.rst files from the SPDX License
Identifier check, since they are documentational files, like *.txt. 
Here is the warning message I got on a recent documentation patch I
created.

WARNING: Missing or malformed SPDX-License-Identifier tag in line 1
#28: FILE: Documentation/networking/fm10k.rst:1:
+Linux* Base Driver for Intel(R) Ethernet Multi-host Controller

total: 0 errors, 1 warnings, 0 checks, 162 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-
inplace.

.apply/v4-Documentation-fm10k-Add-kernel-documentation.patch has style
problems, please review.

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.

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

^ permalink raw reply

* [PATCH net] net/ipv6: Put lwtstate when destroying fib6_info
From: dsahern @ 2018-08-20 20:02 UTC (permalink / raw)
  To: netdev; +Cc: davem, David Ahern

From: David Ahern <dsahern@gmail.com>

Prior to the introduction of fib6_info lwtstate was managed by the dst
code. With fib6_info releasing lwtstate needs to be done when the struct
is freed.

Fixes: 93531c674315 ("net/ipv6: separate handling of FIB entries from dst based routes")
Signed-off-by: David Ahern <dsahern@gmail.com>
---
 net/ipv6/ip6_fib.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index d212738e9d10..c861a6d4671d 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -198,6 +198,8 @@ void fib6_info_destroy_rcu(struct rcu_head *head)
 		}
 	}
 
+	lwtstate_put(f6i->fib6_nh.nh_lwtstate);
+
 	if (f6i->fib6_nh.nh_dev)
 		dev_put(f6i->fib6_nh.nh_dev);
 
-- 
2.11.0

^ permalink raw reply related

* Managed Service Providers (MSPs)
From: joyce.murphy @ 2018-08-20 19:50 UTC (permalink / raw)
  To: netdev

Hi,

I just wanted to check if you would be interested in a list of Managed  
Service Providers (MSPs) and Managed Security Service Providers (MSSPs)?

We also have the data intelligence of:

•       Managed Service Providers (MSP’s)
•       Managed Security Service Providers (MSSP’s)
•       IT Decision Makers – 6million across all industry
•       Business Decision Makers – 10 million across all industry
•       Value Added Resellers- VARs
•       Independent Software Vendors- ISVs
•       System Integrators- SIs
•       VoIP Service Providers.
•       Telecommunications Service Providers (TSPs)
•       Application Service Providers (ASPs)
•       IT Managed Services Providers (ITMSP)
•       Storage Service Providers (SSPs)

Kindly review and let me know if I can share more information on this.

I look forward to hearing from you.

Regards,
Joyce
Marketing Specialist

If you don't want to include yourself in our mailing list, please reply  
back “Leave Out"" in a subject line"

^ permalink raw reply

* r8169 needs CONFIG_REALTEK_PHY
From: Marc Dionne @ 2018-08-20 19:44 UTC (permalink / raw)
  To: hkallweit1, netdev, David Miller

The r8169 adapter in one of my machines was not working after updating
to a current kernel from the merge window, which was fixed by enabling
CONFIG_REALTEK_PHY.

So in addition to "select PHYLIB", should CONFIG_R8169 not also be
doing "select CONFIG_REALTEK_PHY" ?

Marc

^ permalink raw reply

* Re: [PATCH v3 net-next] dt-bindings: can: rcar_can: document r8a77965 support
From: Rob Herring @ 2018-08-20 19:37 UTC (permalink / raw)
  To: Eugeniu Rosca
  Cc: Simon Horman, Kieran Bingham, Sergei Shtylyov,
	Wolfgang Grandegger, Marc Kleine-Budde, David S . Miller,
	Mark Rutland, linux-can, netdev, devicetree, Magnus Damm,
	linux-renesas-soc, Eugeniu Rosca, Eugeniu Rosca
In-Reply-To: <20180820144910.13210-1-erosca@de.adit-jv.com>

On Mon, 20 Aug 2018 16:49:10 +0200, Eugeniu Rosca wrote:
> From: Eugeniu Rosca <rosca.eugeniu@gmail.com>
> 
> Document the support for rcar_can on R8A77965 SoC devices.
> Add R8A77965 to the list of SoCs which require the "assigned-clocks" and
> "assigned-clock-rates" properties (thanks, Sergei).
> 
> Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com>
> Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
> Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> ---
> Changes in v3:
>  - [Simon Horman] Added more recipients.
>  - [Simon Horman] Dropped redundant "can" word in summary line.
>  - [Simon Horman] Added Reviewed-by.
>  - [Kieran Bingham] Added Reviewed-by.
> Changes in v2:
>  - [Kieran Bingham] Simplified commit description. Rewrapped text.
>  - [Sergei Shtylyov] Replaced footnotes with inline text.
>  - Pushed all dt-bindings patches to the beginning of the series.
> ---
>  Documentation/devicetree/bindings/net/can/rcar_can.txt | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* ixgbe hangs when XDP_TX is enabled
From: Nikita V. Shirokov @ 2018-08-20 19:31 UTC (permalink / raw)
  To: netdev; +Cc: alexander.h.duyck, jeffrey.t.kirsher

we are getting such errors:

[  408.737313] ixgbe 0000:03:00.0 eth0: Detected Tx Unit Hang (XDP)
                 Tx Queue             <46>
                 TDH, TDT             <0>, <2>
                 next_to_use          <2>
                 next_to_clean        <0>
               tx_buffer_info[next_to_clean]
                 time_stamp           <0>
                 jiffies              <1000197c0>
[  408.804438] ixgbe 0000:03:00.0 eth0: tx hang 1 detected on queue 46, resetting adapter
[  408.804440] ixgbe 0000:03:00.0 eth0: initiating reset due to tx timeout
[  408.817679] ixgbe 0000:03:00.0 eth0: Reset adapter
[  408.866091] ixgbe 0000:03:00.0 eth0: TXDCTL.ENABLE for one or more queues not cleared within the polling period
[  409.345289] ixgbe 0000:03:00.0 eth0: detected SFP+: 3
[  409.497232] ixgbe 0000:03:00.0 eth0: NIC Link is Up 10 Gbps, Flow Control: RX/TX

while running XDP prog on ixgbe nic.
right now i'm seing this on bpfnext kernel 
(latest commit from Wed Aug 15 15:04:25 2018 -0700 ;
9a76aba02a37718242d7cdc294f0a3901928aa57)

looks like this is the same issue as reported by Brenden in
https://www.spinics.net/lists/netdev/msg439438.html

^ permalink raw reply

* Re: [PATCH] bonding: avoid repeated display of same link status change
From: rama nichanamatlu @ 2018-08-20 19:02 UTC (permalink / raw)
  To: netdev, David Miller
In-Reply-To: <1534191017-25630-1-git-send-email-rama.nichanamatlu@oracle.com>

gentle request. may i have review comments pls ?

-Rama
On 08/13/2018 01:10 PM, Rama Nichanamatlu wrote:
> When link status change needs to be committed and rtnl lock couldn't be
> taken, avoid redisplay of same link status change message.
>
> Signed-off-by: Rama Nichanamatlu <rama.nichanamatlu@oracle.com>
> ---
>   drivers/net/bonding/bond_main.c |    6 ++++--
>   include/net/bonding.h           |    1 +
>   2 files changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> index 63e3844..3dd1091 100644
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -2086,7 +2086,7 @@ static int bond_miimon_inspect(struct bonding *bond)
>   			bond_propose_link_state(slave, BOND_LINK_FAIL);
>   			commit++;
>   			slave->delay = bond->params.downdelay;
> -			if (slave->delay) {
> +			if (slave->delay && !bond->rtnl_needed) {
>   				netdev_info(bond->dev, "link status down for %sinterface %s, disabling it in %d ms\n",
>   					    (BOND_MODE(bond) ==
>   					     BOND_MODE_ACTIVEBACKUP) ?
> @@ -2126,7 +2126,7 @@ static int bond_miimon_inspect(struct bonding *bond)
>   			commit++;
>   			slave->delay = bond->params.updelay;
>   
> -			if (slave->delay) {
> +			if (slave->delay && !bond->rtnl_needed) {
>   				netdev_info(bond->dev, "link status up for interface %s, enabling it in %d ms\n",
>   					    slave->dev->name,
>   					    ignore_updelay ? 0 :
> @@ -2300,9 +2300,11 @@ static void bond_mii_monitor(struct work_struct *work)
>   		if (!rtnl_trylock()) {
>   			delay = 1;
>   			should_notify_peers = false;
> +			bond->rtnl_needed = true;
>   			goto re_arm;
>   		}
>   
> +		bond->rtnl_needed = false;
>   		bond_for_each_slave(bond, slave, iter) {
>   			bond_commit_link_state(slave, BOND_SLAVE_NOTIFY_LATER);
>   		}
> diff --git a/include/net/bonding.h b/include/net/bonding.h
> index 808f1d1..50d61cf 100644
> --- a/include/net/bonding.h
> +++ b/include/net/bonding.h
> @@ -234,6 +234,7 @@ struct bonding {
>   	struct	 dentry *debug_dir;
>   #endif /* CONFIG_DEBUG_FS */
>   	struct rtnl_link_stats64 bond_stats;
> +	bool rtnl_needed;
>   };
>   
>   #define bond_slave_get_rcu(dev) \

^ permalink raw reply

* Re: [PATCH net v2 0/4] qed: Misc fixes in the interface with the MFW
From: David Miller @ 2018-08-20 18:35 UTC (permalink / raw)
  To: Tomer.Tayar; +Cc: netdev
In-Reply-To: <1534712505-31090-1-git-send-email-Tomer.Tayar@cavium.com>

From: Tomer Tayar <Tomer.Tayar@cavium.com>
Date: Mon, 20 Aug 2018 00:01:41 +0300

> This patch series fixes several issues in the driver's interface with the
> management FW (MFW).
> 
> v1->v2:
> - Fix loop counter decrement to be pre instead of post.

Series applied, thank you.

^ permalink raw reply

* Re: [Patch net 8/9] act_ife: move tcfa_lock down to where necessary
From: David Miller @ 2018-08-20 18:29 UTC (permalink / raw)
  To: xiyou.wangcong; +Cc: netdev, jhs, vladbu
In-Reply-To: <20180819192213.14196-9-xiyou.wangcong@gmail.com>

From: Cong Wang <xiyou.wangcong@gmail.com>
Date: Sun, 19 Aug 2018 12:22:12 -0700

> The only time we need to take tcfa_lock is when adding
> a new metainfo to an existing ife->metalist. We don't need
> to take tcfa_lock so early and so broadly in tcf_ife_init().
> 
> This means we can always take ife_mod_lock first, avoid the
> reverse locking ordering warning as reported by Vlad.
> 
> Reported-by: Vlad Buslov <vladbu@mellanox.com>
> Tested-by: Vlad Buslov <vladbu@mellanox.com>
> Cc: Vlad Buslov <vladbu@mellanox.com>
> Cc: Jamal Hadi Salim <jhs@mojatatu.com>
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>

After this change we no longer call populate_metalist() in an atomic
context via tcf_ife_init(), and populate_metalist passes 'exists'
down to add_metainfo() as an 'atomic' indicator.  It doesn't have this
meaning if you aren't holding the tcfa_lock in the callers with BH
disabled.

Therefore, add_metainfo()'s 'atomic' indication is inaccurate in this
call chain and will use GFP_ATOMIC unnecessarily.

Probably the thing to just is just pass 'false' down to add_metainfo()
in populate_metalist().

^ permalink raw reply

* Re: [PATCH v2 06/29] mtd: Add support for reading MTD devices via the nvmem API
From: Boris Brezillon @ 2018-08-20 18:20 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Alban, Bartosz Golaszewski, Jonathan Corbet, Sekhar Nori,
	Kevin Hilman, Russell King, Arnd Bergmann, Greg Kroah-Hartman,
	David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Naren, Mauro Carvalho Chehab,
	Andrew Morton, Lukas Wunner, Dan Carpenter, Florian Fainelli
In-Reply-To: <5b8c30b8-41e1-d59e-542b-fef6c6469ff0@linaro.org>

On Mon, 20 Aug 2018 11:43:34 +0100
Srinivas Kandagatla <srinivas.kandagatla@linaro.org> wrote:

> 
> Overall am still not able to clear visualize on how MTD bindings with 
> nvmem cells would look in both partition and un-partition usecases?
> An example DT would be nice here!!

Something along those lines:

	mtdnode {
		nvmem-cells {
			#address-cells = <1>;
			#size-cells = <1>;

			cell@0 {
				reg = <0x0 0x14>;
			};
		};

		partitions {
			compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

			partition@0 {
				reg = <0x0 0x20000>;

				nvmem-cells {
					#address-cells = <1>;
					#size-cells = <1>;

					cell@0 {
						reg = <0x0 0x10>;
					};
				};
			};
		};
	};

^ permalink raw reply

* [PATCH 2/2] staging: rtl8712u: Fix compiler warning about strncpy
From: Larry Finger @ 2018-08-20 17:51 UTC (permalink / raw)
  To: gregkh; +Cc: netdev, devel, Larry Finger
In-Reply-To: <20180820175124.23863-1-Larry.Finger@lwfinger.net>

When strncpy() is called with source and destination strings the same
length, gcc 8 warns that there may be an unterminated string. Using
strlcpy() rather than strncpy() forces a null at the end and quiets the
warning.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
 drivers/staging/rtl8712/rtl871x_ioctl_linux.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
index c3ff7c3e6681..08e1c0957a07 100644
--- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
@@ -1789,7 +1789,7 @@ static int r871x_wx_set_enc_ext(struct net_device *dev,
 		return -ENOMEM;
 	param->cmd = IEEE_CMD_SET_ENCRYPTION;
 	eth_broadcast_addr(param->sta_addr);
-	strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
+	strlcpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
 	if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
 		param->u.crypt.set_tx = 0;
 	if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
-- 
2.18.0

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox