Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH v6 1/6] can: dev: Add support for limiting configured bitrate
From: Marc Kleine-Budde @ 2018-01-02 13:00 UTC (permalink / raw)
  To: Faiz Abbas, wg, robh+dt, mark.rutland
  Cc: linux-can, netdev, devicetree, linux-kernel, nsekhar, fcooper,
	robh, Wenyou.Yang, sergei.shtylyov
In-Reply-To: <1513949488-13026-2-git-send-email-faiz_abbas@ti.com>


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

On 12/22/2017 02:31 PM, Faiz Abbas wrote:
> From: Franklin S Cooper Jr <fcooper@ti.com>
> 
> Various CAN or CAN-FD IP may be able to run at a faster rate than
> what the transceiver the CAN node is connected to. This can lead to
> unexpected errors. However, CAN transceivers typically have fixed
> limitations and provide no means to discover these limitations at
> runtime. Therefore, add support for a can-transceiver node that
> can be reused by other CAN peripheral drivers to determine for both
> CAN and CAN-FD what the max bitrate that can be used. If the user
> tries to configure CAN to pass these maximum bitrates it will throw
> an error.
> 
> Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com>
> [nsekhar@ti.com: fix build error with !CONFIG_OF]
> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
> Signed-off-by: Faiz Abbas <faiz_abbas@ti.com>
> ---
> v6 changes:
> fix build error with !CONFIG_OF
> 
>  drivers/net/can/dev.c   | 39 +++++++++++++++++++++++++++++++++++++++
>  include/linux/can/dev.h |  8 ++++++++
>  2 files changed, 47 insertions(+)
> 
> diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
> index 365a8cc..007cfc0 100644
> --- a/drivers/net/can/dev.c
> +++ b/drivers/net/can/dev.c
> @@ -27,6 +27,7 @@
>  #include <linux/can/skb.h>
>  #include <linux/can/netlink.h>
>  #include <linux/can/led.h>
> +#include <linux/of.h>
>  #include <net/rtnetlink.h>
>  
>  #define MOD_DESC "CAN device driver interface"
> @@ -814,6 +815,30 @@ int open_candev(struct net_device *dev)
>  }
>  EXPORT_SYMBOL_GPL(open_candev);
>  
> +#ifdef CONFIG_OF
> +/*
> + * Common function that can be used to understand the limitation of
> + * a transceiver when it provides no means to determine these limitations
> + * at runtime.
> + */
> +void of_can_transceiver(struct net_device *dev)
> +{
> +	struct device_node *dn;
> +	struct can_priv *priv = netdev_priv(dev);
> +	struct device_node *np = dev->dev.parent->of_node;
> +	int ret;
> +
> +	dn = of_get_child_by_name(np, "can-transceiver");
> +	if (!dn)
> +		return;
> +
> +	ret = of_property_read_u32(dn, "max-bitrate", &priv->max_bitrate);
> +	if ((ret && ret != -EINVAL) || (!ret && !priv->max_bitrate))
> +		netdev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit.\n");
> +}
> +EXPORT_SYMBOL_GPL(of_can_transceiver);
> +#endif
> +
>  /*
>   * Common close function for cleanup before the device gets closed.
>   *
> @@ -913,6 +938,13 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
>  					priv->bitrate_const_cnt);
>  		if (err)
>  			return err;
> +
> +		if (priv->max_bitrate && bt.bitrate > priv->max_bitrate) {
> +			netdev_err(dev, "arbitration bitrate surpasses transceiver capabilities of %d bps\n",
> +				   priv->max_bitrate);
> +			return -EINVAL;
> +		}

What about movong this check into can_get_bittiming()? Although we loose
the "arbitration" vs "canfd data".

> +
>  		memcpy(&priv->bittiming, &bt, sizeof(bt));
>  
>  		if (priv->do_set_bittiming) {
> @@ -997,6 +1029,13 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
>  					priv->data_bitrate_const_cnt);
>  		if (err)
>  			return err;
> +
> +		if (priv->max_bitrate && dbt.bitrate > priv->max_bitrate) {
> +			netdev_err(dev, "canfd data bitrate surpasses transceiver capabilities of %d bps\n",
> +				   priv->max_bitrate);
> +			return -EINVAL;
> +		}
> +
>  		memcpy(&priv->data_bittiming, &dbt, sizeof(dbt));
>  
>  		if (priv->do_set_data_bittiming) {
> diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
> index 61f1cf2..fbb7810 100644
> --- a/include/linux/can/dev.h
> +++ b/include/linux/can/dev.h
> @@ -48,6 +48,8 @@ struct can_priv {
>  	unsigned int data_bitrate_const_cnt;
>  	struct can_clock clock;
>  
> +	unsigned int max_bitrate;

Please make it an u32, name it "bitrate_max" and ...

>> struct can_priv {
>> 	struct net_device *dev;
>> 	struct can_device_stats can_stats;
>> 
>> 	struct can_bittiming bittiming, data_bittiming;
>> 	const struct can_bittiming_const *bittiming_const,
>> 		*data_bittiming_const;
>> 	const u16 *termination_const;
>> 	unsigned int termination_const_cnt;
>> 	u16 termination;
>> 	const u32 *bitrate_const;
>> 	unsigned int bitrate_const_cnt;
>> 	const u32 *data_bitrate_const;
>> 	unsigned int data_bitrate_const_cnt;

...move it here.

>> 	struct can_clock clock;
> 

> +
>  	enum can_state state;
>  
>  	/* CAN controller features - see include/uapi/linux/can/netlink.h */
> @@ -166,6 +168,12 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
>  unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx);
>  void can_free_echo_skb(struct net_device *dev, unsigned int idx);
>  
> +#ifdef CONFIG_OF
> +void of_can_transceiver(struct net_device *dev);
> +#else
> +static inline void of_can_transceiver(struct net_device *dev) { }
> +#endif
> +
>  struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf);
>  struct sk_buff *alloc_canfd_skb(struct net_device *dev,
>  				struct canfd_frame **cfd);
> 

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


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

^ permalink raw reply

* Re: [PATCH net-next 4/7] net: phy: add paged phy register accessors
From: Andrew Lunn @ 2018-01-02 13:14 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: Florian Fainelli, netdev
In-Reply-To: <20180102105020.GA21998@n2100.armlinux.org.uk>

> I've decided to solve this by changing it to:
> 
> + * phy_restore_page() must always be called after this, irrespective
> + * of success or failure of this call.
> 
> iow, not explaining /why/.

Hi Russell

That is fine by my. A quick read of the code makes it clear why.

     Andrew

^ permalink raw reply

* Re: [net-next: PATCH v2 5/5] net: mvpp2: enable ACPI support in the driver
From: Andrew Lunn @ 2018-01-02 13:33 UTC (permalink / raw)
  To: Marcin Wojtas
  Cc: linux-kernel, linux-arm-kernel, netdev, linux-acpi,
	Graeme Gregory, David S. Miller, Russell King - ARM Linux,
	Rafael J. Wysocki, Florian Fainelli, Antoine Ténart,
	Thomas Petazzoni, Gregory Clément, Ezequiel Garcia, nadavh,
	Neta Zur Hershkovits, Ard Biesheuvel, Grzegorz Jaszczyk
In-Reply-To: <CAPv3WKdr8MaPJi1_PnMfmmk3PeSrJBLUoE8gRCEzwbJsMKBaZg@mail.gmail.com>

> Apart from the phylink's SFP support that may require in-band
> management, it's an alternative to the normal PHY handling. Once MDIO
> bus + PHYs are supported for ACPI, phylib support will be used instead
> of the IRQs, so there should be no problem here.

Hi Marcin

However, phylib and phylink can use IRQs. The PHY can interrupt when
there is a change of state. This can be seen in the DT binding
documentation example:

ethernet-phy@0 {
        compatible = "ethernet-phy-id0141.0e90", "ethernet-phy-ieee802.3-c22";
        interrupt-parent = <&PIC>;
        interrupts = <35 IRQ_TYPE_EDGE_RISING>;
        reg = <0>;

Whatever ACPI support you propose needs to include interrupts.

May i suggest you take a look at
arch/arm/boot/dts/vf610-zii-dev-rev-c.dts and ensure your ACPI work
can support this. I know you tend to concentrate of Marvell parts.
Although it is a Freescale SoC, the Ethernet parts are all Marvell.

The SoC exports an MDIO bus. We then have an MDIO multiplexer, which
exports 8 MDIO busses. Of these only 2 are used in this design. Each
bus has an Ethernet switch. Each switch has an MDIO bus, which the
embedded PHYs are on. The Ethernet switch is also an interrupt
controller for the PHYs interrupts. So the PHYs have interrupt
properties pointing back to the switch.

	   Andrew




^ permalink raw reply

* Re: [PATCH v6 4/6] can: m_can: Support higher speed CAN-FD bitrates
From: Marc Kleine-Budde @ 2018-01-02 13:35 UTC (permalink / raw)
  To: Faiz Abbas, wg, robh+dt, mark.rutland
  Cc: linux-can, netdev, devicetree, linux-kernel, nsekhar, fcooper,
	robh, Wenyou.Yang, sergei.shtylyov
In-Reply-To: <1513949488-13026-5-git-send-email-faiz_abbas@ti.com>


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

On 12/22/2017 02:31 PM, Faiz Abbas wrote:
> From: Franklin S Cooper Jr <fcooper@ti.com>
> 
> During test transmitting using CAN-FD at high bitrates (> 2 Mbps)
> would fail. Scoping the signals I noticed that only a single bit
> was being transmitted and with a bit more investigation realized the actual
> MCAN IP would go back to initialization mode automatically.
> 
> It appears this issue is due to the MCAN needing to use the Transmitter
> Delay Compensation Mode with the correct value for the transmitter delay
> compensation offset (tdco). What impacts the tdco value isn't 100% clear
> but to calculate it you use an equation defined in the MCAN User's Guide.
> 
> The user guide mentions that this register needs to be set based on clock
> values, secondary sample point and the data bitrate. One of the key
> variables that can't automatically be determined is the secondary
> sample point (ssp). This ssp is similar to the sp but is specific to this
> transmitter delay compensation mode. The guidelines for configuring
> ssp is rather vague but via some CAN test it appears for DRA76x that putting
> the value same as data sampling point works.
> 
> The CAN-CIA's "Bit Time Requirements for CAN FD" paper presented at
> the International CAN Conference 2013 indicates that this TDC mode is
> only needed for data bit rates above 2.5 Mbps. Therefore, only enable
> this mode when the data bit rate is above 2.5 Mbps.
> 
> Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com>
> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
> Signed-off-by: Faiz Abbas <faiz_abbas@ti.com>
> ---
>  drivers/net/can/m_can/m_can.c | 41 ++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 40 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
> index 53e764f..371ffc1 100644
> --- a/drivers/net/can/m_can/m_can.c
> +++ b/drivers/net/can/m_can/m_can.c
> @@ -127,6 +127,12 @@ enum m_can_mram_cfg {
>  #define DBTP_DSJW_SHIFT		0
>  #define DBTP_DSJW_MASK		(0xf << DBTP_DSJW_SHIFT)
>  
> +/* Transmitter Delay Compensation Register (TDCR) */
> +#define TDCR_TDCO_SHIFT		8
> +#define TDCR_TDCO_MASK		(0x7F << TDCR_TDCO_SHIFT)
> +#define TDCR_TDCF_SHIFT		0
> +#define TDCR_TDCF_MASK		(0x7F << TDCR_TDCF_SHIFT)
> +
>  /* Test Register (TEST) */
>  #define TEST_LBCK		BIT(4)
>  
> @@ -991,7 +997,8 @@ static int m_can_set_bittiming(struct net_device *dev)
>  	const struct can_bittiming *bt = &priv->can.bittiming;
>  	const struct can_bittiming *dbt = &priv->can.data_bittiming;
>  	u16 brp, sjw, tseg1, tseg2;
> -	u32 reg_btp;
> +	u32 reg_btp, tdco, ssp;

Please move the tdco and the ssp into "if (dbt->bitrate > 2500000)" scope.

Initialize "reg_btp = 0", see below.

> +	bool enable_tdc = false;

Please remove, see below.

>  
>  	brp = bt->brp - 1;
>  	sjw = bt->sjw - 1;
> @@ -1006,9 +1013,41 @@ static int m_can_set_bittiming(struct net_device *dev)
>  		sjw = dbt->sjw - 1;
>  		tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1;
>  		tseg2 = dbt->phase_seg2 - 1;
> +
> +		/* TDC is only needed for bitrates beyond 2.5 MBit/s.
> +		 * This is mentioned in the "Bit Time Requirements for CAN FD"
> +		 * paper presented at the International CAN Conference 2013
> +		 */
> +		if (dbt->bitrate > 2500000) {
> +			/* Use the same value of secondary sampling point
> +			 * as the data sampling point
> +			 */
> +			ssp = dbt->sample_point;
> +
> +			/* Equation based on Bosch's M_CAN User Manual's
> +			 * Transmitter Delay Compensation Section
> +			 */
> +			tdco = (priv->can.clock.freq / 1000) *
> +			       ssp / dbt->bitrate;
> +
> +			/* Max valid TDCO value is 127 */
> +			if (tdco > 127) {
> +				netdev_warn(dev, "TDCO value of %u is beyond maximum limit. Disabling Transmitter Delay Compensation mode\n",

"maximum limit"? Either "maximum" or "limit" should be enough. If the
value is above 127, does it make sense to disable the tdco completely?

> +					    tdco);
> +			} else {
> +				enable_tdc = true;

Why not set "reg_btp |= DBTP_TDC;" here directly?

> +				m_can_write(priv, M_CAN_TDCR,
> +					    tdco << TDCR_TDCO_SHIFT);
> +			}
> +		}
> +
>  		reg_btp = (brp << DBTP_DBRP_SHIFT) | (sjw << DBTP_DSJW_SHIFT) |
>  			(tseg1 << DBTP_DTSEG1_SHIFT) |
>  			(tseg2 << DBTP_DTSEG2_SHIFT);

Adjust this to "reg_btp |=".

> +
> +		if (enable_tdc)
> +			reg_btp |= DBTP_TDC;

Please remove.

> +
>  		m_can_write(priv, M_CAN_DBTP, reg_btp);
>  	}
>  
> 

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


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

^ permalink raw reply

* Re: [patch net-next v2 00/10] Add support for resource abstraction
From: Andrew Lunn @ 2018-01-02 13:41 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Arkadi Sharshevsky, netdev, dsa, roopa, davem, mlxsw,
	vivien.didelot, f.fainelli, michael.chan, ganeshgr, saeedm,
	matanb, leonro, idosch, jakub.kicinski, ast, daniel, simon.horman,
	pieter.jansenvanvuuren, john.hurley, alexander.h.duyck, linville,
	gospo, steven.lin1, yuvalm, ogerlitz
In-Reply-To: <20180102100817.GB2051@nanopsycho.orion>

> Question is where to put it. It is mlxsw-specific thing, moreover,
> Spectrum-specific thing, same as dpipe tables etc. Not sure. Perhaps
> Documentation/networking/mlxsw.txt ?

Hi Jiri

Documentation/ABI seems like the correct place. There is nothing in
the README which says it is limited to files. You could use an name
like devlink-driver-mlxsw.

     Andrew

^ permalink raw reply

* Re: [Cluster-devel] [PATCH 00/12] drop unneeded newline
From: Bob Peterson @ 2018-01-02 13:52 UTC (permalink / raw)
  To: Julia Lawall
  Cc: dev, linux-s390, linux-media, linux-scsi, dccp,
	Alexander Shishkin, netdev, kernel-janitors, linux-kernel,
	dri-devel, cluster-devel, amd-gfx, Namhyung Kim, linux-ext4,
	Jiri Olsa, linux-arm-kernel, esc storagedev
In-Reply-To: <1514386305-7402-1-git-send-email-Julia.Lawall@lip6.fr>

----- Original Message -----
| Drop newline at the end of a message string when the printing function adds
| a newline.

Hi Julia,

NACK.

As much as it's a pain when searching the source code for output strings,
this patch set goes against the accepted Linux coding style document. See:

https://www.kernel.org/doc/html/v4.10/process/coding-style.html#breaking-long-lines-and-strings

Regards,

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

^ permalink raw reply

* Re: [Cluster-devel] [PATCH 00/12] drop unneeded newline
From: Julia Lawall @ 2018-01-02 13:55 UTC (permalink / raw)
  To: Bob Peterson
  Cc: Julia Lawall, dri-devel, dev, linux-s390, linux-scsi, dccp,
	Alexander Shishkin, netdev, kernel-janitors, linux-kernel,
	amd-gfx, cluster-devel, esc storagedev, Namhyung Kim, linux-ext4,
	Jiri Olsa, linux-arm-kernel, linux-media
In-Reply-To: <1878806802.2632123.1514901158666.JavaMail.zimbra@redhat.com>



On Tue, 2 Jan 2018, Bob Peterson wrote:

> ----- Original Message -----
> | Drop newline at the end of a message string when the printing function adds
> | a newline.
>
> Hi Julia,
>
> NACK.
>
> As much as it's a pain when searching the source code for output strings,
> this patch set goes against the accepted Linux coding style document. See:
>
> https://www.kernel.org/doc/html/v4.10/process/coding-style.html#breaking-long-lines-and-strings

I don't think that's the case:

"However, never break user-visible strings such as printk messages,
because that breaks the ability to grep for them."

julia

>
> Regards,
>
> Bob Peterson
> --
> To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* Re: [net-next: PATCH v2 5/5] net: mvpp2: enable ACPI support in the driver
From: Marcin Wojtas @ 2018-01-02 13:55 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: linux-kernel, linux-arm-kernel, netdev, linux-acpi,
	Graeme Gregory, David S. Miller, Russell King - ARM Linux,
	Rafael J. Wysocki, Florian Fainelli, Antoine Ténart,
	Thomas Petazzoni, Gregory Clément, Ezequiel Garcia, nadavh,
	Neta Zur Hershkovits, Ard Biesheuvel, Grzegorz Jaszczyk,
	Tomasz Nowicki
In-Reply-To: <20180102133347.GB15036@lunn.ch>

Hi Andrew,

2018-01-02 14:33 GMT+01:00 Andrew Lunn <andrew@lunn.ch>:
>> Apart from the phylink's SFP support that may require in-band
>> management, it's an alternative to the normal PHY handling. Once MDIO
>> bus + PHYs are supported for ACPI, phylib support will be used instead
>> of the IRQs, so there should be no problem here.
>
> Hi Marcin
>
> However, phylib and phylink can use IRQs. The PHY can interrupt when
> there is a change of state. This can be seen in the DT binding
> documentation example:
>
> ethernet-phy@0 {
>         compatible = "ethernet-phy-id0141.0e90", "ethernet-phy-ieee802.3-c22";
>         interrupt-parent = <&PIC>;
>         interrupts = <35 IRQ_TYPE_EDGE_RISING>;
>         reg = <0>;
>
> Whatever ACPI support you propose needs to include interrupts.
>
> May i suggest you take a look at
> arch/arm/boot/dts/vf610-zii-dev-rev-c.dts and ensure your ACPI work
> can support this. I know you tend to concentrate of Marvell parts.
> Although it is a Freescale SoC, the Ethernet parts are all Marvell.
>
> The SoC exports an MDIO bus. We then have an MDIO multiplexer, which
> exports 8 MDIO busses. Of these only 2 are used in this design. Each
> bus has an Ethernet switch. Each switch has an MDIO bus, which the
> embedded PHYs are on. The Ethernet switch is also an interrupt
> controller for the PHYs interrupts. So the PHYs have interrupt
> properties pointing back to the switch.
>

I thought you were pointing possible problems in mvpp2 with PHY/link
interrupts, sorry. Now I get it :)

Indeed in of_mdio_bus_register_phy, there is of_irq_get. This is more
a discussion for a MDIO bus / ACPI patchset, but we either find a way
to use IRQs with ACPI obtained from child nodes or for this world the
functionality will be limited (at least for the beginning).

Best regards,
Marcin

^ permalink raw reply

* Re: [Cluster-devel] [PATCH 00/12] drop unneeded newline
From: Bob Peterson @ 2018-01-02 13:56 UTC (permalink / raw)
  To: Julia Lawall
  Cc: dev, linux-s390, linux-media, linux-scsi, dccp,
	Alexander Shishkin, netdev, kernel-janitors, linux-kernel,
	dri-devel, cluster-devel, amd-gfx, Namhyung Kim, linux-ext4,
	Jiri Olsa, linux-arm-kernel, esc storagedev
In-Reply-To: <1878806802.2632123.1514901158666.JavaMail.zimbra@redhat.com>

----- Original Message -----
| ----- Original Message -----
| | Drop newline at the end of a message string when the printing function adds
| | a newline.
| 
| Hi Julia,
| 
| NACK.
| 
| As much as it's a pain when searching the source code for output strings,
| this patch set goes against the accepted Linux coding style document. See:
| 
| https://www.kernel.org/doc/html/v4.10/process/coding-style.html#breaking-long-lines-and-strings
| 
| Regards,
| 
| Bob Peterson
| 
| 
Hm. I guess I stand corrected. The document reads:

"However, never break user-visible strings such as printk messages, because that breaks the ability to grep for them."

Still, the GFS2 and DLM code has a plethora of broken-up printk messages,
and I don't like the thought of re-combining them all.

Regards,

Bob Peterson

^ permalink raw reply

* Re: [patch iproute2 v3 1/4] lib/libnetlink: Add a function rtnl_talk_msg
From: Chris Mi @ 2018-01-02 13:59 UTC (permalink / raw)
  To: David Ahern, netdev; +Cc: gerlitz.or, stephen
In-Reply-To: <75c29c60-2886-6ffe-f9c7-8bc67862adc6@gmail.com>


> On 12/25/17 2:46 AM, Chris Mi wrote:
>> diff --git a/lib/libnetlink.c b/lib/libnetlink.c
>> index 00e6ce0c..f5f675cf 100644
>> --- a/lib/libnetlink.c
>> +++ b/lib/libnetlink.c
>> @@ -581,36 +581,21 @@ static void rtnl_talk_error(struct nlmsghdr *h, struct nlmsgerr *err,
>>   		strerror(-err->error));
>>   }
>>   
>> -static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
>> -		       struct nlmsghdr **answer,
>> -		       bool show_rtnl_err, nl_ext_ack_fn_t errfn)
>> +static int __rtnl_check_ack(struct rtnl_handle *rtnl, struct nlmsghdr **answer,
> Make this function __rtnl_talk_msg. Include the assignment of nlmsg_seq
> and ack setting using the for loop below and sendmsg() call. All of that
> code can be common for both the single and multiple iov case.
Thanks for your suggestion. Done.
>
>> +		       bool show_rtnl_err, nl_ext_ack_fn_t errfn,
>> +		       unsigned int seq)
>>   {
>>   	int status;
>> -	unsigned int seq;
>> -	struct nlmsghdr *h;
>> +	char *buf;
> Please order variables in the reverse xmas tree style used in the net code.
Actually, I divide the variables in two parts, none-struct variables and 
struct variables.
Not sure if that meets the reverse xmac tree style, but I think it is 
more readable.
>
>>   	struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
>> -	struct iovec iov = {
>> -		.iov_base = n,
>> -		.iov_len = n->nlmsg_len
>> -	};
>> +	struct nlmsghdr *h;
>> +	struct iovec iov;
>>   	struct msghdr msg = {
>>   		.msg_name = &nladdr,
>>   		.msg_namelen = sizeof(nladdr),
>>   		.msg_iov = &iov,
>>   		.msg_iovlen = 1,
>>   	};
>> -	char *buf;
>> -
>> -	n->nlmsg_seq = seq = ++rtnl->seq;
>> -
>> -	if (answer == NULL)
>> -		n->nlmsg_flags |= NLM_F_ACK;
>> -
>> -	status = sendmsg(rtnl->fd, &msg, 0);
>> -	if (status < 0) {
>> -		perror("Cannot talk to rtnetlink");
>> -		return -1;
>> -	}
>>   
>>   	while (1) {
>>   		status = rtnl_recvmsg(rtnl->fd, &msg, &buf);

^ permalink raw reply

* Re: [Cluster-devel] [PATCH 00/12] drop unneeded newline
From: Julia Lawall @ 2018-01-02 14:00 UTC (permalink / raw)
  To: Bob Peterson
  Cc: dev-yBygre7rU0TnMu66kgdUjQ, linux-s390-u79uwXL29TY76Z2rM5mHXA,
	linux-scsi-u79uwXL29TY76Z2rM5mHXA, dccp-u79uwXL29TY76Z2rM5mHXA,
	Alexander Shishkin, netdev-u79uwXL29TY76Z2rM5mHXA,
	kernel-janitors-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	cluster-devel-H+wXaHxf7aLQT0dZR+AlfA,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, esc storagedev,
	Namhyung Kim, linux-ext4-u79uwXL29TY76Z2rM5mHXA, Jiri Olsa,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-media-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1019862289.2632779.1514901387442.JavaMail.zimbra-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>



On Tue, 2 Jan 2018, Bob Peterson wrote:

> ----- Original Message -----
> | ----- Original Message -----
> | | Drop newline at the end of a message string when the printing function adds
> | | a newline.
> |
> | Hi Julia,
> |
> | NACK.
> |
> | As much as it's a pain when searching the source code for output strings,
> | this patch set goes against the accepted Linux coding style document. See:
> |
> | https://www.kernel.org/doc/html/v4.10/process/coding-style.html#breaking-long-lines-and-strings
> |
> | Regards,
> |
> | Bob Peterson
> |
> |
> Hm. I guess I stand corrected. The document reads:
>
> "However, never break user-visible strings such as printk messages, because that breaks the ability to grep for them."
>
> Still, the GFS2 and DLM code has a plethora of broken-up printk messages,
> and I don't like the thought of re-combining them all.

Actually, the point of the patch was to remove the unnecessary \n at the
end of the string, because log_print will add another one.  If you prefer
to keep the string broken up, I can resend the patch in that form, but
without the unnecessary \n.

julia

^ permalink raw reply

* Re: [patch iproute2 v3 2/4] utils: Add a function setcmdlinetotal
From: Chris Mi @ 2018-01-02 14:03 UTC (permalink / raw)
  To: David Ahern, netdev; +Cc: gerlitz.or, stephen
In-Reply-To: <695fea40-a786-ce97-c3a8-b5411a6894fd@gmail.com>


> On 12/25/17 2:46 AM, Chris Mi wrote:
>> This function calculates how many commands a batch file has and
>> set it to global variable cmdlinetotal.
>>
>> Signed-off-by: Chris Mi <chrism@mellanox.com>
>> ---
>>   include/utils.h |  4 ++++
>>   lib/utils.c     | 20 ++++++++++++++++++++
>>   2 files changed, 24 insertions(+)
>>
>> diff --git a/include/utils.h b/include/utils.h
>> index d3895d56..113a8c31 100644
>> --- a/include/utils.h
>> +++ b/include/utils.h
>> @@ -235,6 +235,10 @@ void print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n);
>>   
>>   extern int cmdlineno;
>>   ssize_t getcmdline(char **line, size_t *len, FILE *in);
>> +
>> +extern int cmdlinetotal;
>> +void setcmdlinetotal(const char *name);
>> +
>>   int makeargs(char *line, char *argv[], int maxargs);
>>   int inet_get_addr(const char *src, __u32 *dst, struct in6_addr *dst6);
>>   
>> diff --git a/lib/utils.c b/lib/utils.c
>> index 7ced8c06..53ca389f 100644
>> --- a/lib/utils.c
>> +++ b/lib/utils.c
>> @@ -1202,6 +1202,26 @@ ssize_t getcmdline(char **linep, size_t *lenp, FILE *in)
>>   	return cc;
>>   }
>>   
>> +int cmdlinetotal;
>> +
>> +void setcmdlinetotal(const char *name)
>> +{
>> +	char *line = NULL;
>> +	size_t len = 0;
>> +
>> +	if (name && strcmp(name, "-") != 0) {
>> +		if (freopen(name, "r", stdin) == NULL) {
>> +			fprintf(stderr, "Cannot open file \"%s\" for reading: %s\n",
>> +				name, strerror(errno));
>> +			return;
>> +		}
>> +	}
>> +
>> +	cmdlinetotal = 0;
>> +	while (getcmdline(&line, &len, stdin) != -1)
>> +		cmdlinetotal++;
>> +}
>> +
>>   /* split command line into argument vector */
>>   int makeargs(char *line, char *argv[], int maxargs)
>>   {
>>
> This helper should not be needed. There is no need to read what could be
> a million+ line file multiple times.
Done. I removed this helper. But we can't simply use !feof directly.
I figure out a way to determine if we are reaching the end of file by
reading one more line of the batch file.

^ permalink raw reply

* Re: [net-next: PATCH v2 5/5] net: mvpp2: enable ACPI support in the driver
From: Andrew Lunn @ 2018-01-02 14:08 UTC (permalink / raw)
  To: Marcin Wojtas
  Cc: linux-kernel, linux-arm-kernel, netdev, linux-acpi,
	Graeme Gregory, David S. Miller, Russell King - ARM Linux,
	Rafael J. Wysocki, Florian Fainelli, Antoine Ténart,
	Thomas Petazzoni, Gregory Clément, Ezequiel Garcia, nadavh,
	Neta Zur Hershkovits, Ard Biesheuvel, Grzegorz Jaszczyk
In-Reply-To: <CAPv3WKfB6_5hPw2M_GOMHVc_soPyzgMqQJ=tG5qOfSe_397z9A@mail.gmail.com>

> Indeed in of_mdio_bus_register_phy, there is of_irq_get. This is more
> a discussion for a MDIO bus / ACPI patchset, but we either find a way
> to use IRQs with ACPI obtained from child nodes or for this world the
> functionality will be limited (at least for the beginning).

Hi Marcin

What i want to avoid is adding something which partially works, and
then have to throw it all away and start again in order to add full
support.

If ACPI really limits interrupts to devices, maybe we need a totally
different representation of MDIO and PHYs in ACPI to what it used in
device tree? The same may be true for the Ethernet ports of the mvpp2?
They might have to be represented as real devices, not children of a
device? Maybe trying to map DT to ACPI on a one-to-one basis is the
wrong approach?

	Andrew

^ permalink raw reply

* Re: [patch iproute2 v3 3/4] tc: Add -bs option to batch mode
From: Chris Mi @ 2018-01-02 14:17 UTC (permalink / raw)
  To: David Ahern, netdev; +Cc: gerlitz.or, stephen
In-Reply-To: <28563dd5-01be-9198-2911-658bbd0ba3d7@gmail.com>


> On 12/25/17 2:46 AM, Chris Mi wrote:
>> Signed-off-by: Chris Mi <chrism@mellanox.com>
>> ---
>>   tc/m_action.c  |  91 +++++++++++++++++++++++++++++++++----------
>>   tc/tc.c        |  47 ++++++++++++++++++----
>>   tc/tc_common.h |   8 +++-
>>   tc/tc_filter.c | 121 +++++++++++++++++++++++++++++++++++++++++----------------
>>   4 files changed, 204 insertions(+), 63 deletions(-)
>>
>> diff --git a/tc/m_action.c b/tc/m_action.c
>> index fc422364..c4c3b862 100644
>> --- a/tc/m_action.c
>> +++ b/tc/m_action.c
>> @@ -23,6 +23,7 @@
>>   #include <arpa/inet.h>
>>   #include <string.h>
>>   #include <dlfcn.h>
>> +#include <errno.h>
>>   
>>   #include "utils.h"
>>   #include "tc_common.h"
>> @@ -546,40 +547,88 @@ bad_val:
>>   	return ret;
>>   }
>>   
>> +typedef struct {
>> +	struct nlmsghdr		n;
>> +	struct tcamsg		t;
>> +	char			buf[MAX_MSG];
>> +} tc_action_req;
>> +
>> +static tc_action_req *action_reqs;
>> +static struct iovec msg_iov[MSG_IOV_MAX];
>> +
>> +void free_action_reqs(void)
>> +{
>> +	free(action_reqs);
>> +}
>> +
>> +static tc_action_req *get_action_req(int batch_size, int index)
>> +{
>> +	tc_action_req *req;
>> +
>> +	if (action_reqs == NULL) {
>> +		action_reqs = malloc(batch_size * sizeof (tc_action_req));
>> +		if (action_reqs == NULL)
>> +			return NULL;
>> +	}
>> +	req = &action_reqs[index];
>> +	memset(req, 0, sizeof (*req));
>> +
>> +	return req;
>> +}
>> +
>>   static int tc_action_modify(int cmd, unsigned int flags,
>> -			    int *argc_p, char ***argv_p)
>> +			    int *argc_p, char ***argv_p,
>> +			    int batch_size, int index, bool send)
>>   {
>>   	int argc = *argc_p;
>>   	char **argv = *argv_p;
>>   	int ret = 0;
>> -	struct {
>> -		struct nlmsghdr         n;
>> -		struct tcamsg           t;
>> -		char                    buf[MAX_MSG];
>> -	} req = {
>> -		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcamsg)),
>> -		.n.nlmsg_flags = NLM_F_REQUEST | flags,
>> -		.n.nlmsg_type = cmd,
>> -		.t.tca_family = AF_UNSPEC,
>> +	tc_action_req *req;
>> +	struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
>> +	struct iovec *iov = &msg_iov[index];
>> +
>> +	req = get_action_req(batch_size, index);
>> +	if (req == NULL) {
>> +		fprintf(stderr, "get_action_req error: not enough buffer\n");
>> +		return -ENOMEM;
>> +	}
>> +
>> +	req->n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcamsg));
>> +	req->n.nlmsg_flags = NLM_F_REQUEST | flags;
>> +	req->n.nlmsg_type = cmd;
>> +	req->t.tca_family = AF_UNSPEC;
>> +	struct rtattr *tail = NLMSG_TAIL(&req->n);
>> +
>> +	struct msghdr msg = {
>> +		.msg_name = &nladdr,
>> +		.msg_namelen = sizeof(nladdr),
>> +		.msg_iov = msg_iov,
>> +		.msg_iovlen = index + 1,
>>   	};
>> -	struct rtattr *tail = NLMSG_TAIL(&req.n);
>>   
>>   	argc -= 1;
>>   	argv += 1;
>> -	if (parse_action(&argc, &argv, TCA_ACT_TAB, &req.n)) {
>> +	if (parse_action(&argc, &argv, TCA_ACT_TAB, &req->n)) {
>>   		fprintf(stderr, "Illegal \"action\"\n");
>>   		return -1;
>>   	}
>> -	tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail;
>> +	tail->rta_len = (void *) NLMSG_TAIL(&req->n) - (void *) tail;
>> +
>> +	*argc_p = argc;
>> +	*argv_p = argv;
>> +
>> +	iov->iov_base = &req->n;
>> +	iov->iov_len = req->n.nlmsg_len;
>> +
>> +	if (!send)
>> +		return 0;
>>   
>> -	if (rtnl_talk(&rth, &req.n, NULL) < 0) {
>> +	ret = rtnl_talk_msg(&rth, &msg, NULL);
>> +	if (ret < 0) {
>>   		fprintf(stderr, "We have an error talking to the kernel\n");
>>   		ret = -1;
>>   	}
>>   
>> -	*argc_p = argc;
>> -	*argv_p = argv;
>> -
>>   	return ret;
>>   }
>>   
>> @@ -679,7 +728,7 @@ bad_val:
>>   	return ret;
>>   }
>>   
>> -int do_action(int argc, char **argv)
>> +int do_action(int argc, char **argv, int batch_size, int index, bool send)
>>   {
>>   
>>   	int ret = 0;
>> @@ -689,12 +738,14 @@ int do_action(int argc, char **argv)
>>   		if (matches(*argv, "add") == 0) {
>>   			ret =  tc_action_modify(RTM_NEWACTION,
>>   						NLM_F_EXCL | NLM_F_CREATE,
>> -						&argc, &argv);
>> +						&argc, &argv, batch_size,
>> +						index, send);
>>   		} else if (matches(*argv, "change") == 0 ||
>>   			  matches(*argv, "replace") == 0) {
>>   			ret = tc_action_modify(RTM_NEWACTION,
>>   					       NLM_F_CREATE | NLM_F_REPLACE,
>> -					       &argc, &argv);
>> +					       &argc, &argv, batch_size,
>> +					       index, send);
>>   		} else if (matches(*argv, "delete") == 0) {
>>   			argc -= 1;
>>   			argv += 1;
>> diff --git a/tc/tc.c b/tc/tc.c
>> index ad9f07e9..7ea2fc89 100644
>> --- a/tc/tc.c
>> +++ b/tc/tc.c
>> @@ -189,20 +189,20 @@ static void usage(void)
>>   	fprintf(stderr, "Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }\n"
>>   			"       tc [-force] -batch filename\n"
>>   			"where  OBJECT := { qdisc | class | filter | action | monitor | exec }\n"
>> -	                "       OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -p[retty] | -b[atch] [filename] | -n[etns] name |\n"
>> +	                "       OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -p[retty] | -b[atch] [filename] | -bs | -batchsize [size] | -n[etns] name |\n"
>>   			"                    -nm | -nam[es] | { -cf | -conf } path } | -j[son]\n");
>>   }
>>   
>> -static int do_cmd(int argc, char **argv)
>> +static int do_cmd(int argc, char **argv, int batch_size, int index, bool send)
>>   {
>>   	if (matches(*argv, "qdisc") == 0)
>>   		return do_qdisc(argc-1, argv+1);
>>   	if (matches(*argv, "class") == 0)
>>   		return do_class(argc-1, argv+1);
>>   	if (matches(*argv, "filter") == 0)
>> -		return do_filter(argc-1, argv+1);
>> +		return do_filter(argc-1, argv+1, batch_size, index, send);
>>   	if (matches(*argv, "actions") == 0)
>> -		return do_action(argc-1, argv+1);
>> +		return do_action(argc-1, argv+1, batch_size, index, send);
>>   	if (matches(*argv, "monitor") == 0)
>>   		return do_tcmonitor(argc-1, argv+1);
>>   	if (matches(*argv, "exec") == 0)
>> @@ -217,11 +217,16 @@ static int do_cmd(int argc, char **argv)
>>   	return -1;
>>   }
>>   
>> -static int batch(const char *name)
>> +static int batch(const char *name, int batch_size)
>>   {
>> +	int msg_iov_index = 0;
>>   	char *line = NULL;
>>   	size_t len = 0;
>>   	int ret = 0;
>> +	bool send;
>> +
>> +	if (batch_size > 1)
>> +		setcmdlinetotal(name);
>>   
>>   	batch_mode = 1;
>>   	if (name && strcmp(name, "-") != 0) {
>> @@ -248,15 +253,30 @@ static int batch(const char *name)
>>   		if (largc == 0)
>>   			continue;	/* blank line */
>>   
>> -		if (do_cmd(largc, largv)) {
>> +		/*
>> +		 * In batch mode, if we haven't accumulated enough commands
>> +		 * and this is not the last command, don't send the message
>> +		 * immediately.
>> +		 */
>> +		if (batch_size > 1 && msg_iov_index + 1 != batch_size
>> +		    && cmdlineno != cmdlinetotal)
>> +			send = false;
>> +		else
>> +			send = true;
>> +
>> +		ret = do_cmd(largc, largv, batch_size, msg_iov_index++, send);
> What happens if tc commands are interlaced in the file -- qdisc add,
> class add, filter add, then a delete, show, exec, etc.? Right now each
> command is handled one at a time so an add followed by a delete will
> work. Your proposed batching loop won't work for this case as some
> commands are executed when that line is reached and others are batched
> for later send. Not all of the tc commands need to be batched in a
> single message so perhaps those commands cause the queue to be flushed
> (ie, message sent), then that command is executed and you start the
> batching over.
Maybe you are right. But the intention of this patch is to improve the 
insertion rate.
We can use it as benchmark tool. So we only care about the filter add or 
action add.
If the user mixes many different subcommands in one batch file, I don't 
think he can
get any benfit from this patch. Maybe he should ignore the -bs option.
>
> Further, I really think the batching can be done without the global
> variables and without the command handlers knowing it is batching or
> part of an iov. e.g., in the case of batching try having the commands
> malloc the request buffer and return the pointer back to this loop in
> which case this loop calls rtnl_talk_msg and frees the buffers.
But not all of these commands will end up calling rtnl_talk. They may do 
different things.
I think current code is clear and easy to maitain, I mean the functions 
do_xxx.
If I change the code as you suggested, I think function batch will be 
very complex
and hard to maitain.
>
>> +		if (ret < 0) {
>>   			fprintf(stderr, "Command failed %s:%d\n", name, cmdlineno);
>>   			ret = 1;
>>   			if (!force)
>>   				break;
>>   		}
>> +		msg_iov_index %= batch_size;
>>   	}
>>   	if (line)
>>   		free(line);
>> +	free_filter_reqs();
>> +	free_action_reqs();
>>   
>>   	rtnl_close(&rth);
>>   	return ret;

^ permalink raw reply

* Re: [patch iproute2 v3 3/4] tc: Add -bs option to batch mode
From: Chris Mi @ 2018-01-02 14:19 UTC (permalink / raw)
  To: Marcelo Ricardo Leitner; +Cc: netdev, gerlitz.or, stephen, dsahern
In-Reply-To: <20171227195609.GA22042@localhost.localdomain>


> On Mon, Dec 25, 2017 at 05:46:57PM +0900, Chris Mi wrote:
>> @@ -267,6 +287,7 @@ int main(int argc, char **argv)
>>   {
>>   	int ret;
>>   	char *batch_file = NULL;
>> +	int batch_size = 1;
>>   
>>   	while (argc > 1) {
>>   		if (argv[1][0] != '-')
>> @@ -297,6 +318,14 @@ int main(int argc, char **argv)
>>   			if (argc <= 1)
>>   				usage();
>>   			batch_file = argv[1];
>> +		} else if (matches(argv[1], "-batchsize") == 0 ||
>> +				matches(argv[1], "-bs") == 0) {
>> +			argc--;	argv++;
>> +			if (argc <= 1)
>> +				usage();
>> +			batch_size = atoi(argv[1]);
>> +			if (batch_size > MSG_IOV_MAX)
>> +				batch_size = MSG_IOV_MAX;
> what about
> if (batch_size < 1)
> 	batch_size = 1;
Done.
>
>>   		} else if (matches(argv[1], "-netns") == 0) {
>>   			NEXT_ARG();
>>   			if (netns_switch(argv[1]))

^ permalink raw reply

* [patch iproute2 v4 0/3] tc: Add -bs option to batch mode
From: Chris Mi @ 2018-01-02 14:28 UTC (permalink / raw)
  To: netdev; +Cc: gerlitz.or, stephen, dsahern, marcelo.leitner, Chris Mi

Currently in tc batch mode, only one command is read from the batch
file and sent to kernel to process. With this patchset, we can
accumulate
several commands before sending to kernel. The batch size is specified
using option -bs or -batchsize.

To accumulate the commands in tc, client should allocate an array of
struct iovec. If batchsize is bigger than 1, only after the client
has accumulated enough commands, can the client call rtnl_talk_msg
to send the message that includes the iov array. One exception is
that there is no more command in the batch file.

But please note that kernel still processes the requests one by one.
To process the requests in parallel in kernel is another effort.
The time we're saving in this patchset is the user mode and kernel mode
context switch. So this patchset works on top of the current kernel.

Using the following script in kernel, we can generate 1,000,000 rules.
        tools/testing/selftests/tc-testing/tdc_batch.py

Without this patchset, 'tc -b $file' exection time is:

real    0m15.125s
user    0m6.982s
sys     0m8.080s

With this patchset, 'tc -b $file -bs 10' exection time is:

real    0m12.772s
user    0m5.984s
sys     0m6.723s

The insertion rate is improved more than 10%.

In this patchset, we still ack for every rule. If we don't ack at all,

'tc -b $file' exection time is:

real    0m14.484s
user    0m6.919s
sys     0m7.498s

'tc -b $file -bs 10' exection time is:

real    0m11.664s
user    0m6.017s
sys     0m5.578s


We can see that the performance win is to send multiple messages instead
of no acking. I think that's because in tc, we don't spend too much time
processing the ack message.


v3
==
1. Instead of hacking function rtnl_talk directly, add a new function
   rtnl_talk_msg.
2. remove most of global variables to use parameter passing
3. divide the previous patch into 4 patches.

v4
==
1. Remove function setcmdlinetotal. Now in function batch, we read one
   more line to determine if we are reaching the end of file.
2. Remove function __rtnl_check_ack. Now __rtnl_talk calls __rtnl_talk_msg
   directly.
3. if (batch_size < 1)
	batch_size = 1;

Chris Mi (3):
  lib/libnetlink: Add a function rtnl_talk_msg
  tc: Add -bs option to batch mode
  man: Add -bs option to tc manpage

 include/libnetlink.h |   3 ++
 lib/libnetlink.c     |  59 ++++++++++++++++++-------
 man/man8/tc.8        |   5 +++
 tc/m_action.c        |  90 +++++++++++++++++++++++++++++---------
 tc/tc.c              |  69 +++++++++++++++++++++++------
 tc/tc_common.h       |   8 +++-
 tc/tc_filter.c       | 121 +++++++++++++++++++++++++++++++++++++--------------
 7 files changed, 271 insertions(+), 84 deletions(-)

-- 
2.14.3

^ permalink raw reply

* [patch iproute2 v4 1/3] lib/libnetlink: Add a function rtnl_talk_msg
From: Chris Mi @ 2018-01-02 14:28 UTC (permalink / raw)
  To: netdev; +Cc: gerlitz.or, stephen, dsahern, marcelo.leitner, Chris Mi
In-Reply-To: <20180102142804.27145-1-chrism@mellanox.com>

rtnl_talk can only send a single message to kernel. Add a new function
rtnl_talk_msg that can send multiple messages to kernel.

Signed-off-by: Chris Mi <chrism@mellanox.com>
---
 include/libnetlink.h |  3 +++
 lib/libnetlink.c     | 59 ++++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 46 insertions(+), 16 deletions(-)

diff --git a/include/libnetlink.h b/include/libnetlink.h
index a4d83b9e..01d98b16 100644
--- a/include/libnetlink.h
+++ b/include/libnetlink.h
@@ -96,6 +96,9 @@ int rtnl_dump_filter_nc(struct rtnl_handle *rth,
 int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
 	      struct nlmsghdr **answer)
 	__attribute__((warn_unused_result));
+int rtnl_talk_msg(struct rtnl_handle *rtnl, struct msghdr *m,
+		  struct nlmsghdr **answer)
+	__attribute__((warn_unused_result));
 int rtnl_talk_extack(struct rtnl_handle *rtnl, struct nlmsghdr *n,
 	      struct nlmsghdr **answer, nl_ext_ack_fn_t errfn)
 	__attribute__((warn_unused_result));
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index 00e6ce0c..cc02a139 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -581,32 +581,34 @@ static void rtnl_talk_error(struct nlmsghdr *h, struct nlmsgerr *err,
 		strerror(-err->error));
 }
 
-static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
-		       struct nlmsghdr **answer,
-		       bool show_rtnl_err, nl_ext_ack_fn_t errfn)
+static int __rtnl_talk_msg(struct rtnl_handle *rtnl, struct msghdr *m,
+			   struct nlmsghdr **answer,
+			   bool show_rtnl_err, nl_ext_ack_fn_t errfn)
 {
-	int status;
-	unsigned int seq;
-	struct nlmsghdr *h;
+	int iovlen = m->msg_iovlen;
+	unsigned int seq = 0;
+	int i, status;
+	char *buf;
+
 	struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
-	struct iovec iov = {
-		.iov_base = n,
-		.iov_len = n->nlmsg_len
-	};
+	struct iovec iov, *v;
+	struct nlmsghdr *h;
 	struct msghdr msg = {
 		.msg_name = &nladdr,
 		.msg_namelen = sizeof(nladdr),
 		.msg_iov = &iov,
 		.msg_iovlen = 1,
 	};
-	char *buf;
 
-	n->nlmsg_seq = seq = ++rtnl->seq;
-
-	if (answer == NULL)
-		n->nlmsg_flags |= NLM_F_ACK;
+	for (i = 0; i < iovlen; i++) {
+		v = &m->msg_iov[i];
+		h = v->iov_base;
+		h->nlmsg_seq = seq = ++rtnl->seq;
+		if (answer == NULL)
+			h->nlmsg_flags |= NLM_F_ACK;
+	}
 
-	status = sendmsg(rtnl->fd, &msg, 0);
+	status = sendmsg(rtnl->fd, m, 0);
 	if (status < 0) {
 		perror("Cannot talk to rtnetlink");
 		return -1;
@@ -698,12 +700,37 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
 	}
 }
 
+static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
+		       struct nlmsghdr **answer,
+		       bool show_rtnl_err, nl_ext_ack_fn_t errfn)
+{
+	struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
+	struct iovec iov = {
+		.iov_base = n,
+		.iov_len = n->nlmsg_len
+	};
+	struct msghdr msg = {
+		.msg_name = &nladdr,
+		.msg_namelen = sizeof(nladdr),
+		.msg_iov = &iov,
+		.msg_iovlen = 1,
+	};
+
+	return __rtnl_talk_msg(rtnl, &msg, answer, show_rtnl_err, errfn);
+}
+
 int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
 	      struct nlmsghdr **answer)
 {
 	return __rtnl_talk(rtnl, n, answer, true, NULL);
 }
 
+int rtnl_talk_msg(struct rtnl_handle *rtnl, struct msghdr *m,
+	      struct nlmsghdr **answer)
+{
+	return __rtnl_talk_msg(rtnl, m, answer, true, NULL);
+}
+
 int rtnl_talk_extack(struct rtnl_handle *rtnl, struct nlmsghdr *n,
 		     struct nlmsghdr **answer,
 		     nl_ext_ack_fn_t errfn)
-- 
2.14.3

^ permalink raw reply related

* [patch iproute2 v4 2/3] tc: Add -bs option to batch mode
From: Chris Mi @ 2018-01-02 14:28 UTC (permalink / raw)
  To: netdev; +Cc: gerlitz.or, stephen, dsahern, marcelo.leitner, Chris Mi
In-Reply-To: <20180102142804.27145-1-chrism@mellanox.com>

Signed-off-by: Chris Mi <chrism@mellanox.com>
---
 tc/m_action.c  |  90 ++++++++++++++++++++++++++++++++----------
 tc/tc.c        |  69 +++++++++++++++++++++++++-------
 tc/tc_common.h |   8 +++-
 tc/tc_filter.c | 121 +++++++++++++++++++++++++++++++++++++++++----------------
 4 files changed, 220 insertions(+), 68 deletions(-)

diff --git a/tc/m_action.c b/tc/m_action.c
index fc422364..2e79034d 100644
--- a/tc/m_action.c
+++ b/tc/m_action.c
@@ -23,6 +23,7 @@
 #include <arpa/inet.h>
 #include <string.h>
 #include <dlfcn.h>
+#include <errno.h>
 
 #include "utils.h"
 #include "tc_common.h"
@@ -546,40 +547,87 @@ bad_val:
 	return ret;
 }
 
+typedef struct {
+	struct nlmsghdr		n;
+	struct tcamsg		t;
+	char			buf[MAX_MSG];
+} tc_action_req;
+
+static tc_action_req *action_reqs;
+static struct iovec msg_iov[MSG_IOV_MAX];
+
+void free_action_reqs(void)
+{
+	free(action_reqs);
+}
+
+static tc_action_req *get_action_req(int batch_size, int index)
+{
+	tc_action_req *req;
+
+	if (action_reqs == NULL) {
+		action_reqs = malloc(batch_size * sizeof (tc_action_req));
+		if (action_reqs == NULL)
+			return NULL;
+	}
+	req = &action_reqs[index];
+	memset(req, 0, sizeof (*req));
+
+	return req;
+}
+
 static int tc_action_modify(int cmd, unsigned int flags,
-			    int *argc_p, char ***argv_p)
+			    int *argc_p, char ***argv_p,
+			    int batch_size, int index, bool send)
 {
 	int argc = *argc_p;
 	char **argv = *argv_p;
 	int ret = 0;
-	struct {
-		struct nlmsghdr         n;
-		struct tcamsg           t;
-		char                    buf[MAX_MSG];
-	} req = {
-		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcamsg)),
-		.n.nlmsg_flags = NLM_F_REQUEST | flags,
-		.n.nlmsg_type = cmd,
-		.t.tca_family = AF_UNSPEC,
+	tc_action_req *req;
+	struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
+	struct iovec *iov = &msg_iov[index];
+
+	req = get_action_req(batch_size, index);
+	if (req == NULL) {
+		fprintf(stderr, "get_action_req error: not enough buffer\n");
+		return -ENOMEM;
+	}
+
+	req->n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcamsg));
+	req->n.nlmsg_flags = NLM_F_REQUEST | flags;
+	req->n.nlmsg_type = cmd;
+	req->t.tca_family = AF_UNSPEC;
+	struct rtattr *tail = NLMSG_TAIL(&req->n);
+
+	struct msghdr msg = {
+		.msg_name = &nladdr,
+		.msg_namelen = sizeof(nladdr),
+		.msg_iov = msg_iov,
+		.msg_iovlen = index + 1,
 	};
-	struct rtattr *tail = NLMSG_TAIL(&req.n);
 
 	argc -= 1;
 	argv += 1;
-	if (parse_action(&argc, &argv, TCA_ACT_TAB, &req.n)) {
+	if (parse_action(&argc, &argv, TCA_ACT_TAB, &req->n)) {
 		fprintf(stderr, "Illegal \"action\"\n");
 		return -1;
 	}
-	tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail;
+	tail->rta_len = (void *) NLMSG_TAIL(&req->n) - (void *) tail;
+
+	*argc_p = argc;
+	*argv_p = argv;
+
+	iov->iov_base = &req->n;
+	iov->iov_len = req->n.nlmsg_len;
+
+	if (!send)
+		return 0;
 
-	if (rtnl_talk(&rth, &req.n, NULL) < 0) {
+	if (rtnl_talk_msg(&rth, &msg, NULL) < 0) {
 		fprintf(stderr, "We have an error talking to the kernel\n");
 		ret = -1;
 	}
 
-	*argc_p = argc;
-	*argv_p = argv;
-
 	return ret;
 }
 
@@ -679,7 +727,7 @@ bad_val:
 	return ret;
 }
 
-int do_action(int argc, char **argv)
+int do_action(int argc, char **argv, int batch_size, int index, bool send)
 {
 
 	int ret = 0;
@@ -689,12 +737,14 @@ int do_action(int argc, char **argv)
 		if (matches(*argv, "add") == 0) {
 			ret =  tc_action_modify(RTM_NEWACTION,
 						NLM_F_EXCL | NLM_F_CREATE,
-						&argc, &argv);
+						&argc, &argv, batch_size,
+						index, send);
 		} else if (matches(*argv, "change") == 0 ||
 			  matches(*argv, "replace") == 0) {
 			ret = tc_action_modify(RTM_NEWACTION,
 					       NLM_F_CREATE | NLM_F_REPLACE,
-					       &argc, &argv);
+					       &argc, &argv, batch_size,
+					       index, send);
 		} else if (matches(*argv, "delete") == 0) {
 			argc -= 1;
 			argv += 1;
diff --git a/tc/tc.c b/tc/tc.c
index ad9f07e9..61edda3c 100644
--- a/tc/tc.c
+++ b/tc/tc.c
@@ -189,20 +189,20 @@ static void usage(void)
 	fprintf(stderr, "Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }\n"
 			"       tc [-force] -batch filename\n"
 			"where  OBJECT := { qdisc | class | filter | action | monitor | exec }\n"
-	                "       OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -p[retty] | -b[atch] [filename] | -n[etns] name |\n"
+	                "       OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -p[retty] | -b[atch] [filename] | -bs | -batchsize [size] | -n[etns] name |\n"
 			"                    -nm | -nam[es] | { -cf | -conf } path } | -j[son]\n");
 }
 
-static int do_cmd(int argc, char **argv)
+static int do_cmd(int argc, char **argv, int batch_size, int index, bool send)
 {
 	if (matches(*argv, "qdisc") == 0)
 		return do_qdisc(argc-1, argv+1);
 	if (matches(*argv, "class") == 0)
 		return do_class(argc-1, argv+1);
 	if (matches(*argv, "filter") == 0)
-		return do_filter(argc-1, argv+1);
+		return do_filter(argc-1, argv+1, batch_size, index, send);
 	if (matches(*argv, "actions") == 0)
-		return do_action(argc-1, argv+1);
+		return do_action(argc-1, argv+1, batch_size, index, send);
 	if (matches(*argv, "monitor") == 0)
 		return do_tcmonitor(argc-1, argv+1);
 	if (matches(*argv, "exec") == 0)
@@ -217,11 +217,15 @@ static int do_cmd(int argc, char **argv)
 	return -1;
 }
 
-static int batch(const char *name)
+static int batch(const char *name, int batch_size)
 {
+	bool lastline = false;
+	int msg_iov_index = 0;
+	char *line2 = NULL;
 	char *line = NULL;
 	size_t len = 0;
 	int ret = 0;
+	bool send;
 
 	batch_mode = 1;
 	if (name && strcmp(name, "-") != 0) {
@@ -240,23 +244,49 @@ static int batch(const char *name)
 	}
 
 	cmdlineno = 0;
-	while (getcmdline(&line, &len, stdin) != -1) {
+	if (getcmdline(&line, &len, stdin) == -1)
+		goto Exit;
+	do {
 		char *largv[100];
 		int largc;
 
+		if (getcmdline(&line2, &len, stdin) == -1)
+			lastline = true;
+
 		largc = makeargs(line, largv, 100);
 		if (largc == 0)
 			continue;	/* blank line */
 
-		if (do_cmd(largc, largv)) {
-			fprintf(stderr, "Command failed %s:%d\n", name, cmdlineno);
+		line = line2;
+		line2 = NULL;
+		len = 0;
+
+		/*
+		 * In batch mode, if we haven't accumulated enough commands
+		 * and this is not the last command, don't send the message
+		 * immediately.
+		 */
+		if (batch_size > 1 && msg_iov_index + 1 != batch_size
+		    && !lastline)
+			send = false;
+		else
+			send = true;
+
+		ret = do_cmd(largc, largv, batch_size, msg_iov_index++, send);
+		if (ret < 0) {
+			fprintf(stderr, "Command failed %s:%d\n", name,
+				cmdlineno);
 			ret = 1;
 			if (!force)
 				break;
 		}
-	}
-	if (line)
-		free(line);
+		msg_iov_index %= batch_size;
+	} while (!lastline);
+
+	free_filter_reqs();
+	free_action_reqs();
+Exit:
+	free(line);
 
 	rtnl_close(&rth);
 	return ret;
@@ -267,6 +297,7 @@ int main(int argc, char **argv)
 {
 	int ret;
 	char *batch_file = NULL;
+	int batch_size = 1;
 
 	while (argc > 1) {
 		if (argv[1][0] != '-')
@@ -297,6 +328,16 @@ int main(int argc, char **argv)
 			if (argc <= 1)
 				usage();
 			batch_file = argv[1];
+		} else if (matches(argv[1], "-batchsize") == 0 ||
+				matches(argv[1], "-bs") == 0) {
+			argc--;	argv++;
+			if (argc <= 1)
+				usage();
+			batch_size = atoi(argv[1]);
+			if (batch_size > MSG_IOV_MAX)
+				batch_size = MSG_IOV_MAX;
+			else if (batch_size < 0)
+				batch_size = 1;
 		} else if (matches(argv[1], "-netns") == 0) {
 			NEXT_ARG();
 			if (netns_switch(argv[1]))
@@ -323,7 +364,7 @@ int main(int argc, char **argv)
 	}
 
 	if (batch_file)
-		return batch(batch_file);
+		return batch(batch_file, batch_size);
 
 	if (argc <= 1) {
 		usage();
@@ -341,7 +382,9 @@ int main(int argc, char **argv)
 		goto Exit;
 	}
 
-	ret = do_cmd(argc-1, argv+1);
+	ret = do_cmd(argc-1, argv+1, 1, 0, true);
+	free_filter_reqs();
+	free_action_reqs();
 Exit:
 	rtnl_close(&rth);
 
diff --git a/tc/tc_common.h b/tc/tc_common.h
index 264fbdac..8a82439f 100644
--- a/tc/tc_common.h
+++ b/tc/tc_common.h
@@ -1,13 +1,14 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 
 #define TCA_BUF_MAX	(64*1024)
+#define MSG_IOV_MAX	256
 
 extern struct rtnl_handle rth;
 
 extern int do_qdisc(int argc, char **argv);
 extern int do_class(int argc, char **argv);
-extern int do_filter(int argc, char **argv);
-extern int do_action(int argc, char **argv);
+extern int do_filter(int argc, char **argv, int batch_size, int index, bool send);
+extern int do_action(int argc, char **argv, int batch_size, int index, bool send);
 extern int do_tcmonitor(int argc, char **argv);
 extern int do_exec(int argc, char **argv);
 
@@ -24,5 +25,8 @@ struct tc_sizespec;
 extern int parse_size_table(int *p_argc, char ***p_argv, struct tc_sizespec *s);
 extern int check_size_table_opts(struct tc_sizespec *s);
 
+extern void free_filter_reqs(void);
+extern void free_action_reqs(void);
+
 extern int show_graph;
 extern bool use_names;
diff --git a/tc/tc_filter.c b/tc/tc_filter.c
index 545cc3a1..6fecbb45 100644
--- a/tc/tc_filter.c
+++ b/tc/tc_filter.c
@@ -19,6 +19,7 @@
 #include <arpa/inet.h>
 #include <string.h>
 #include <linux/if_ether.h>
+#include <errno.h>
 
 #include "rt_names.h"
 #include "utils.h"
@@ -42,18 +43,44 @@ static void usage(void)
 		"OPTIONS := ... try tc filter add <desired FILTER_KIND> help\n");
 }
 
-static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
+typedef struct {
+	struct nlmsghdr		n;
+	struct tcmsg		t;
+	char			buf[MAX_MSG];
+} tc_filter_req;
+
+static tc_filter_req *filter_reqs;
+static struct iovec msg_iov[MSG_IOV_MAX];
+
+void free_filter_reqs(void)
 {
-	struct {
-		struct nlmsghdr	n;
-		struct tcmsg		t;
-		char			buf[MAX_MSG];
-	} req = {
-		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)),
-		.n.nlmsg_flags = NLM_F_REQUEST | flags,
-		.n.nlmsg_type = cmd,
-		.t.tcm_family = AF_UNSPEC,
-	};
+	free(filter_reqs);
+}
+
+static tc_filter_req *get_filter_req(int batch_size, int index)
+{
+	tc_filter_req *req;
+
+	if (filter_reqs == NULL) {
+		filter_reqs = malloc(batch_size * sizeof (tc_filter_req));
+		if (filter_reqs == NULL)
+			return NULL;
+	}
+	req = &filter_reqs[index];
+	memset(req, 0, sizeof (*req));
+
+	return req;
+}
+
+static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv,
+			    int batch_size, int index, bool send)
+{
+	tc_filter_req *req;
+	int ret;
+
+	struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
+	struct iovec *iov = &msg_iov[index];
+
 	struct filter_util *q = NULL;
 	__u32 prio = 0;
 	__u32 protocol = 0;
@@ -65,6 +92,24 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
 	char  k[FILTER_NAMESZ] = {};
 	struct tc_estimator est = {};
 
+	req = get_filter_req(batch_size, index);
+	if (req == NULL) {
+		fprintf(stderr, "get_filter_req error: not enough buffer\n");
+		return -ENOMEM;
+	}
+
+	req->n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg));
+	req->n.nlmsg_flags = NLM_F_REQUEST | flags;
+	req->n.nlmsg_type = cmd;
+	req->t.tcm_family = AF_UNSPEC;
+
+	struct msghdr msg = {
+		.msg_name = &nladdr,
+		.msg_namelen = sizeof(nladdr),
+		.msg_iov = msg_iov,
+		.msg_iovlen = index + 1,
+	};
+
 	if (cmd == RTM_NEWTFILTER && flags & NLM_F_CREATE)
 		protocol = htons(ETH_P_ALL);
 
@@ -75,37 +120,37 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
 				duparg("dev", *argv);
 			strncpy(d, *argv, sizeof(d)-1);
 		} else if (strcmp(*argv, "root") == 0) {
-			if (req.t.tcm_parent) {
+			if (req->t.tcm_parent) {
 				fprintf(stderr,
 					"Error: \"root\" is duplicate parent ID\n");
 				return -1;
 			}
-			req.t.tcm_parent = TC_H_ROOT;
+			req->t.tcm_parent = TC_H_ROOT;
 		} else if (strcmp(*argv, "ingress") == 0) {
-			if (req.t.tcm_parent) {
+			if (req->t.tcm_parent) {
 				fprintf(stderr,
 					"Error: \"ingress\" is duplicate parent ID\n");
 				return -1;
 			}
-			req.t.tcm_parent = TC_H_MAKE(TC_H_CLSACT,
+			req->t.tcm_parent = TC_H_MAKE(TC_H_CLSACT,
 						     TC_H_MIN_INGRESS);
 		} else if (strcmp(*argv, "egress") == 0) {
-			if (req.t.tcm_parent) {
+			if (req->t.tcm_parent) {
 				fprintf(stderr,
 					"Error: \"egress\" is duplicate parent ID\n");
 				return -1;
 			}
-			req.t.tcm_parent = TC_H_MAKE(TC_H_CLSACT,
+			req->t.tcm_parent = TC_H_MAKE(TC_H_CLSACT,
 						     TC_H_MIN_EGRESS);
 		} else if (strcmp(*argv, "parent") == 0) {
 			__u32 handle;
 
 			NEXT_ARG();
-			if (req.t.tcm_parent)
+			if (req->t.tcm_parent)
 				duparg("parent", *argv);
 			if (get_tc_classid(&handle, *argv))
 				invarg("Invalid parent ID", *argv);
-			req.t.tcm_parent = handle;
+			req->t.tcm_parent = handle;
 		} else if (strcmp(*argv, "handle") == 0) {
 			NEXT_ARG();
 			if (fhandle)
@@ -152,26 +197,26 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
 		argc--; argv++;
 	}
 
-	req.t.tcm_info = TC_H_MAKE(prio<<16, protocol);
+	req->t.tcm_info = TC_H_MAKE(prio<<16, protocol);
 
 	if (chain_index_set)
-		addattr32(&req.n, sizeof(req), TCA_CHAIN, chain_index);
+		addattr32(&req->n, sizeof(*req), TCA_CHAIN, chain_index);
 
 	if (k[0])
-		addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1);
+		addattr_l(&req->n, sizeof(*req), TCA_KIND, k, strlen(k)+1);
 
 	if (d[0])  {
 		ll_init_map(&rth);
 
-		req.t.tcm_ifindex = ll_name_to_index(d);
-		if (req.t.tcm_ifindex == 0) {
+		req->t.tcm_ifindex = ll_name_to_index(d);
+		if (req->t.tcm_ifindex == 0) {
 			fprintf(stderr, "Cannot find device \"%s\"\n", d);
 			return 1;
 		}
 	}
 
 	if (q) {
-		if (q->parse_fopt(q, fhandle, argc, argv, &req.n))
+		if (q->parse_fopt(q, fhandle, argc, argv, &req->n))
 			return 1;
 	} else {
 		if (fhandle) {
@@ -190,10 +235,17 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
 	}
 
 	if (est.ewma_log)
-		addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est));
+		addattr_l(&req->n, sizeof(*req), TCA_RATE, &est, sizeof(est));
 
-	if (rtnl_talk(&rth, &req.n, NULL) < 0) {
-		fprintf(stderr, "We have an error talking to the kernel\n");
+	iov->iov_base = &req->n;
+	iov->iov_len = req->n.nlmsg_len;
+
+	if (!send)
+		return 0;
+
+	ret = rtnl_talk_msg(&rth, &msg, NULL);
+	if (ret < 0) {
+		fprintf(stderr, "We have an error talking to the kernel, %d\n", ret);
 		return 2;
 	}
 
@@ -636,20 +688,23 @@ static int tc_filter_list(int argc, char **argv)
 	return 0;
 }
 
-int do_filter(int argc, char **argv)
+int do_filter(int argc, char **argv, int batch_size, int index, bool send)
 {
 	if (argc < 1)
 		return tc_filter_list(0, NULL);
 	if (matches(*argv, "add") == 0)
 		return tc_filter_modify(RTM_NEWTFILTER, NLM_F_EXCL|NLM_F_CREATE,
-					argc-1, argv+1);
+					argc-1, argv+1,
+					batch_size, index, send);
 	if (matches(*argv, "change") == 0)
-		return tc_filter_modify(RTM_NEWTFILTER, 0, argc-1, argv+1);
+		return tc_filter_modify(RTM_NEWTFILTER, 0, argc-1, argv+1,
+					batch_size, index, send);
 	if (matches(*argv, "replace") == 0)
 		return tc_filter_modify(RTM_NEWTFILTER, NLM_F_CREATE, argc-1,
-					argv+1);
+					argv+1, batch_size, index, send);
 	if (matches(*argv, "delete") == 0)
-		return tc_filter_modify(RTM_DELTFILTER, 0,  argc-1, argv+1);
+		return tc_filter_modify(RTM_DELTFILTER, 0, argc-1, argv+1,
+					batch_size, index, send);
 	if (matches(*argv, "get") == 0)
 		return tc_filter_get(RTM_GETTFILTER, 0,  argc-1, argv+1);
 	if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
-- 
2.14.3

^ permalink raw reply related

* [patch iproute2 v4 3/3] man: Add -bs option to tc manpage
From: Chris Mi @ 2018-01-02 14:28 UTC (permalink / raw)
  To: netdev; +Cc: gerlitz.or, stephen, dsahern, marcelo.leitner, Chris Mi
In-Reply-To: <20180102142804.27145-1-chrism@mellanox.com>

Signed-off-by: Chris Mi <chrism@mellanox.com>
---
 man/man8/tc.8 | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/man/man8/tc.8 b/man/man8/tc.8
index ff071b33..de137e16 100644
--- a/man/man8/tc.8
+++ b/man/man8/tc.8
@@ -601,6 +601,11 @@ must exist already.
 read commands from provided file or standard input and invoke them.
 First failure will cause termination of tc.
 
+.TP
+.BR "\-bs", " \-bs size", " \-batchsize", " \-batchsize size"
+How many commands are accumulated before sending to kernel.
+By default, it is 1. It only takes effect in batch mode.
+
 .TP
 .BR "\-force"
 don't terminate tc on errors in batch mode.
-- 
2.14.3

^ permalink raw reply related

* Re: [patch net-next v2 00/10] Add support for resource abstraction
From: Jiri Pirko @ 2018-01-02 14:35 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Arkadi Sharshevsky, netdev, dsa, roopa, davem, mlxsw,
	vivien.didelot, f.fainelli, michael.chan, ganeshgr, saeedm,
	matanb, leonro, idosch, jakub.kicinski, ast, daniel, simon.horman,
	pieter.jansenvanvuuren, john.hurley, alexander.h.duyck, linville,
	gospo, steven.lin1, yuvalm, ogerlitz
In-Reply-To: <20180102134113.GC15036@lunn.ch>

Tue, Jan 02, 2018 at 02:41:13PM CET, andrew@lunn.ch wrote:
>> Question is where to put it. It is mlxsw-specific thing, moreover,
>> Spectrum-specific thing, same as dpipe tables etc. Not sure. Perhaps
>> Documentation/networking/mlxsw.txt ?
>
>Hi Jiri
>
>Documentation/ABI seems like the correct place. There is nothing in
>the README which says it is limited to files. You could use an name
>like devlink-driver-mlxsw.

Okay. Sounds sane. Thanks.

^ permalink raw reply

* Re: [net-next: PATCH v2 5/5] net: mvpp2: enable ACPI support in the driver
From: Marcin Wojtas @ 2018-01-02 15:05 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: linux-kernel, linux-arm-kernel, netdev, linux-acpi,
	Graeme Gregory, David S. Miller, Russell King - ARM Linux,
	Rafael J. Wysocki, Florian Fainelli, Antoine Ténart,
	Thomas Petazzoni, Gregory Clément, Ezequiel Garcia, nadavh,
	Neta Zur Hershkovits, Ard Biesheuvel, Grzegorz Jaszczyk,
	Tomasz Nowicki
In-Reply-To: <20180102140852.GE15036@lunn.ch>

2018-01-02 15:08 GMT+01:00 Andrew Lunn <andrew@lunn.ch>:
>> Indeed in of_mdio_bus_register_phy, there is of_irq_get. This is more
>> a discussion for a MDIO bus / ACPI patchset, but we either find a way
>> to use IRQs with ACPI obtained from child nodes or for this world the
>> functionality will be limited (at least for the beginning).
>
> Hi Marcin
>
> What i want to avoid is adding something which partially works, and
> then have to throw it all away and start again in order to add full
> support.
>
> If ACPI really limits interrupts to devices, maybe we need a totally
> different representation of MDIO and PHYs in ACPI to what it used in
> device tree? The same may be true for the Ethernet ports of the mvpp2?
> They might have to be represented as real devices, not children of a
> device? Maybe trying to map DT to ACPI on a one-to-one basis is the
> wrong approach?
>

In terms of PP2 controller, I'd prefer to keep as much as possible to
describing how real hardware looks like, i.e. single common controller
with multiple ports as its children. Those considerations are
reflected in the DT description shape and how the driver enumerates,
which was part of the design of the initial support. Bending the
driver (huge amount of shared initialization and resources) to
multiple instances just for the sake of possible avoidance of IRQ
description in ACPI is IMO a huge and unnecessary overkill.

Anyway, I'll do a more research on the resources / ACPI representation
and will get back with some conclusions. I hope that someone from this
thread recipents will be able to give some advice too :)

Best regards,
Marcin

^ permalink raw reply

* Re: [Cluster-devel] [PATCH 00/12] drop unneeded newline
From: Bart Van Assche @ 2018-01-02 15:11 UTC (permalink / raw)
  To: rpeterso@redhat.com, julia.lawall@lip6.fr
  Cc: kernel-janitors@vger.kernel.org, linux-s390@vger.kernel.org,
	linux-kernel@vger.kernel.org, jolsa@redhat.com,
	linux-media@vger.kernel.org, amd-gfx@lists.freedesktop.org,
	namhyung@kernel.org, linux-scsi@vger.kernel.org,
	esc.storagedev@microsemi.com, dri-devel@lists.freedesktop.org,
	alexander.shishkin@linux.intel.com, dev@openvswitch.org,
	netdev@vger.kernel.org, "linux-arm-kernel@li
In-Reply-To: <alpine.DEB.2.20.1801021458360.24055@hadrien>

On Tue, 2018-01-02 at 15:00 +0100, Julia Lawall wrote:
> On Tue, 2 Jan 2018, Bob Peterson wrote:
> > ----- Original Message -----
> > > ----- Original Message -----
> > >
> > Still, the GFS2 and DLM code has a plethora of broken-up printk messages,
> > and I don't like the thought of re-combining them all.
> 
> Actually, the point of the patch was to remove the unnecessary \n at the
> end of the string, because log_print will add another one.  If you prefer
> to keep the string broken up, I can resend the patch in that form, but
> without the unnecessary \n.

Please combine any user-visible strings into a single line for which the
unneeded newline is dropped since these strings are modified anyway by
your patch.

Thanks,

Bart.

^ permalink raw reply

* Re: [Cluster-devel] [PATCH 00/12] drop unneeded newline
From: Julia Lawall @ 2018-01-02 15:16 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: dev@openvswitch.org, linux-s390@vger.kernel.org,
	linux-scsi@vger.kernel.org, dccp@vger.kernel.org,
	alexander.shishkin@linux.intel.com, esc.storagedev@microsemi.com,
	kernel-janitors@vger.kernel.org, linux-kernel@vger.kernel.org,
	amd-gfx@lists.freedesktop.org, cluster-devel@redhat.com,
	julia.lawall@lip6.fr, dri-devel@lists.freedesktop.org,
	netdev@vger.kernel.org, rpeterso@redhat.com, namhyung@kernel.org,
	"linux-ext4@vger.kernel.
In-Reply-To: <1514905900.4242.4.camel@wdc.com>



On Tue, 2 Jan 2018, Bart Van Assche wrote:

> On Tue, 2018-01-02 at 15:00 +0100, Julia Lawall wrote:
> > On Tue, 2 Jan 2018, Bob Peterson wrote:
> > > ----- Original Message -----
> > > > ----- Original Message -----
> > > >
> > > Still, the GFS2 and DLM code has a plethora of broken-up printk messages,
> > > and I don't like the thought of re-combining them all.
> >
> > Actually, the point of the patch was to remove the unnecessary \n at the
> > end of the string, because log_print will add another one.  If you prefer
> > to keep the string broken up, I can resend the patch in that form, but
> > without the unnecessary \n.
>
> Please combine any user-visible strings into a single line for which the
> unneeded newline is dropped since these strings are modified anyway by
> your patch.

That is what the submitted patch (2/12 specifically) did.

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

^ permalink raw reply

* [PATCH iproute2 0/3] iptnl/tunnel: Open JSON section, kill code duplication and print iptnl mode
From: Serhey Popovych @ 2018-01-02 15:29 UTC (permalink / raw)
  To: netdev

In this series I present following improvements and fixes:

  1) Add missing open_json_context() to link_iptnl.c
     for "encap" options.

  2) Get rid of code duplication when parsing tunnel mode
     parameters in link_iptnl.c.

  3) Add code to link_iptnl.c to print tunnel mode to be
     inline with ip6tnl.

See individual patch description message for details.

Thanks,
Serhii

Serhey Popovych (3):
  link_iptnl: Kill code duplication
  link_iptnl: Print tunnel mode
  link_iptnl: Open "encap" JSON object

 ip/link_iptnl.c |   45 +++++++++++++++++++++++----------------------
 1 file changed, 23 insertions(+), 22 deletions(-)

-- 
1.7.10.4

^ permalink raw reply

* [PATCH iproute2 1/3] link_iptnl: Kill code duplication
From: Serhey Popovych @ 2018-01-02 15:29 UTC (permalink / raw)
  To: netdev
In-Reply-To: <1514906959-9719-1-git-send-email-serhe.popovych@gmail.com>

Both sit and ipip "mode" parameter handling nearly the same.
Except for sit we have "ip6ip" mode: check it only when
configuring sit.

Note that there is no need strcmp(lu->id, "ipip"): if it is
not sit it is "ipip" because we have only these two link util
defined in module.

Signed-off-by: Serhey Popovych <serhe.popovych@gmail.com>
---
 ip/link_iptnl.c |   27 +++++----------------------
 1 file changed, 5 insertions(+), 22 deletions(-)

diff --git a/ip/link_iptnl.c b/ip/link_iptnl.c
index 8a8f5dd..d4d935b 100644
--- a/ip/link_iptnl.c
+++ b/ip/link_iptnl.c
@@ -230,11 +230,11 @@ get_failed:
 		} else if (strcmp(lu->id, "sit") == 0 &&
 			   strcmp(*argv, "isatap") == 0) {
 			iflags |= SIT_ISATAP;
-		} else if (strcmp(lu->id, "sit") == 0 &&
-			   strcmp(*argv, "mode") == 0) {
+		} else if (strcmp(*argv, "mode") == 0) {
 			NEXT_ARG();
-			if (strcmp(*argv, "ipv6/ipv4") == 0 ||
-			    strcmp(*argv, "ip6ip") == 0)
+			if (strcmp(lu->id, "sit") == 0 &&
+			    (strcmp(*argv, "ipv6/ipv4") == 0 ||
+			     strcmp(*argv, "ip6ip") == 0))
 				proto = IPPROTO_IPV6;
 			else if (strcmp(*argv, "ipv4/ipv4") == 0 ||
 				 strcmp(*argv, "ipip") == 0 ||
@@ -248,21 +248,6 @@ get_failed:
 				proto = 0;
 			else
 				invarg("Cannot guess tunnel mode.", *argv);
-		} else if (strcmp(lu->id, "ipip") == 0 &&
-			   strcmp(*argv, "mode") == 0) {
-			NEXT_ARG();
-			if (strcmp(*argv, "ipv4/ipv4") == 0 ||
-				 strcmp(*argv, "ipip") == 0 ||
-				 strcmp(*argv, "ip4ip4") == 0)
-				proto = IPPROTO_IPIP;
-			else if (strcmp(*argv, "mpls/ipv4") == 0 ||
-				   strcmp(*argv, "mplsip") == 0)
-				proto = IPPROTO_MPLS;
-			else if (strcmp(*argv, "any/ipv4") == 0 ||
-				 strcmp(*argv, "any") == 0)
-				proto = 0;
-			else
-				invarg("Cannot guess tunnel mode.", *argv);
 		} else if (strcmp(*argv, "noencap") == 0) {
 			encaptype = TUNNEL_ENCAP_NONE;
 		} else if (strcmp(*argv, "encap") == 0) {
@@ -337,6 +322,7 @@ get_failed:
 		exit(-1);
 	}
 
+	addattr8(n, 1024, IFLA_IPTUN_PROTO, proto);
 	if (metadata) {
 		addattr_l(n, 1024, IFLA_IPTUN_COLLECT_METADATA, NULL, 0);
 		return 0;
@@ -355,9 +341,6 @@ get_failed:
 	addattr16(n, 1024, IFLA_IPTUN_ENCAP_SPORT, htons(encapsport));
 	addattr16(n, 1024, IFLA_IPTUN_ENCAP_DPORT, htons(encapdport));
 
-	if (strcmp(lu->id, "ipip") == 0 || strcmp(lu->id, "sit") == 0)
-		addattr8(n, 1024, IFLA_IPTUN_PROTO, proto);
-
 	if (strcmp(lu->id, "sit") == 0) {
 		addattr16(n, 1024, IFLA_IPTUN_FLAGS, iflags);
 		if (ip6rdprefixlen) {
-- 
1.7.10.4

^ 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