* Re: [PATCH (net.git) 2/3] stmmac: fix PTP support for GMAC4
From: Giuseppe CAVALLARO @ 2016-10-27 10:32 UTC (permalink / raw)
To: Rayagond Kokatanur
Cc: netdev, alexandre.torgue, Richard Cochran, linux-kernel,
seraphin.bonnaffe
In-Reply-To: <CAJ3bTp6Q4XF+nogBNf0ZBq73wr=btmNSgrCg=Kv8kvgsVf2jQg@mail.gmail.com>
Hello Rayagond !
On 10/27/2016 12:25 PM, Rayagond Kokatanur wrote:
>> +static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats)
>> > {
>> > struct dma_desc *p = (struct dma_desc *)desc;
>> > + int ret = -EINVAL;
>> > +
>> > + /* Get the status from normal w/b descriptor */
>> > + if (likely(p->des3 & TDES3_RS1V)) {
>> > + if (likely(p->des1 & RDES1_TIMESTAMP_AVAILABLE)) {
>> > + int i = 0;
>> > +
>> > + /* Check if timestamp is OK from context descriptor */
>> > + do {
>> > + ret = dwmac4_rx_check_timestamp(desc);
> Here, "desc" is not pointing to next descriptor (ie context
> descriptor). Driver should check the context descriptor.
you are right and this is done by the caller: stmmac_get_rx_hwtstamp
Cheers
peppe
^ permalink raw reply
* Re: [patch net-next 3/5] mlxsw: Move PCI id table definitions into driver modules
From: Ivan Vecera @ 2016-10-27 14:39 UTC (permalink / raw)
To: Jiri Pirko, netdev; +Cc: davem, idosch, eladr, yotamg, nogahf, ogerlitz
In-Reply-To: <1477573981-26546-4-git-send-email-jiri@resnulli.us>
Dne 27.10.2016 v 15:12 Jiri Pirko napsal(a):
> From: Jiri Pirko <jiri@mellanox.com>
>
> So far, mlxsw_pci.ko is the module that registers PCI table for all
> drivers (spectrum and switchx2). That is problematic for example with
> dracut. Since mlxsw_spectrum.ko and mlxsw_switchx2.ko are loaded
> dynamically from within mlxsw_core.ko, dracut does not have track of
> them and avoids them from being included in initramfs.
>
> So make this in an ordinary way and define the PCI tables in individual
> driver modules, so it can be properly loaded and included in dracut
> initramfs image. As a side effect, this patch could remove no longer
> necessary driver "kind" strings which were used to link PCI ids with
> individual mlxsw drivers.
>
> Suggested-by: Ivan Vecera <ivecera@redhat.com>
> Tested-by: Ivan Vecera <ivecera@redhat.com>
> Signed-off-by: Jiri Pirko <jiri@mellanox.com>
> Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Thanks Jiri.
Acked-by: Ivan Vecera <ivecera@redhat.com>
^ permalink raw reply
* Re: [PATCH (net.git) 2/3] stmmac: fix PTP support for GMAC4
From: Rayagond Kokatanur @ 2016-10-27 10:25 UTC (permalink / raw)
To: Giuseppe Cavallaro
Cc: netdev, alexandre.torgue, Richard Cochran, linux-kernel,
seraphin.bonnaffe
In-Reply-To: <1477464964-5960-3-git-send-email-peppe.cavallaro@st.com>
Hi Giuseppe,
On Wed, Oct 26, 2016 at 12:26 PM, Giuseppe Cavallaro
<peppe.cavallaro@st.com> wrote:
> Due to bad management of the descriptors, when use ptp4l,
> kernel panics as shown below:
> -----------------------------------------------------------
> Unable to handle kernel NULL pointer dereference at virtual
> address 000001ac
> ...
> Internal error: Oops: 17 [#1] SMP ARM
> ...
> Hardware name: STi SoC with Flattened Device Tree
> task: c0c05e80 task.stack: c0c00000
> PC is at dwmac4_wrback_get_tx_timestamp_status+0x0/0xc
> LR is at stmmac_tx_clean+0x2f8/0x4d4
> -----------------------------------------------------------
>
> In case of GMAC4 the extended descriptor pointers were
> used for getting the timestamp. These are NULL for this HW,
> and the normal ones must be used.
>
> The PTP also had problems on this chip due to the bad
> register management and issues on the algo adopted to
> setup the PTP and getting the timestamp values from the
> descriptors.
>
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
> Cc: Alexandre TORGUE <alexandre.torgue@st.com>
> Cc: Rayagond Kokatanur <rayagond@vayavyalabs.com>
> ---
> drivers/net/ethernet/stmicro/stmmac/common.h | 5 +-
> drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 68 ++++++++++++---
> drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h | 4 +
> drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 +
> .../net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c | 43 ++++++++--
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 97 +++++++++++-----------
> drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 9 +-
> 7 files changed, 154 insertions(+), 73 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index d3292c4..6fc214c 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -482,11 +482,12 @@ struct stmmac_ops {
> /* PTP and HW Timer helpers */
> struct stmmac_hwtimestamp {
> void (*config_hw_tstamping) (void __iomem *ioaddr, u32 data);
> - u32 (*config_sub_second_increment) (void __iomem *ioaddr, u32 clk_rate);
> + u32 (*config_sub_second_increment)(void __iomem *ioaddr, u32 ptp_clock,
> + int gmac4);
> int (*init_systime) (void __iomem *ioaddr, u32 sec, u32 nsec);
> int (*config_addend) (void __iomem *ioaddr, u32 addend);
> int (*adjust_systime) (void __iomem *ioaddr, u32 sec, u32 nsec,
> - int add_sub);
> + int add_sub, int gmac4);
> u64(*get_systime) (void __iomem *ioaddr);
> };
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
> index a1b17cd..2ef2f0c 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
> @@ -204,14 +204,18 @@ static void dwmac4_rd_enable_tx_timestamp(struct dma_desc *p)
>
> static int dwmac4_wrback_get_tx_timestamp_status(struct dma_desc *p)
> {
> - return (p->des3 & TDES3_TIMESTAMP_STATUS)
> - >> TDES3_TIMESTAMP_STATUS_SHIFT;
> + /* Context type from W/B descriptor must be zero */
> + if (p->des3 & TDES3_CONTEXT_TYPE)
> + return -EINVAL;
> +
> + /* Tx Timestamp Status is 1 so des0 and des1'll have valid values */
> + if (p->des3 & TDES3_TIMESTAMP_STATUS)
> + return 0;
> +
> + return 1;
> }
>
> -/* NOTE: For RX CTX bit has to be checked before
> - * HAVE a specific function for TX and another one for RX
> - */
> -static u64 dwmac4_wrback_get_timestamp(void *desc, u32 ats)
> +static inline u64 dwmac4_get_timestamp(void *desc, u32 ats)
> {
> struct dma_desc *p = (struct dma_desc *)desc;
> u64 ns;
> @@ -223,12 +227,54 @@ static u64 dwmac4_wrback_get_timestamp(void *desc, u32 ats)
> return ns;
> }
>
> -static int dwmac4_context_get_rx_timestamp_status(void *desc, u32 ats)
> +static int dwmac4_rx_check_timestamp(void *desc)
> +{
> + struct dma_desc *p = (struct dma_desc *)desc;
> + u32 own, ctxt;
> + int ret = 1;
> +
> + own = p->des3 & RDES3_OWN;
> + ctxt = ((p->des3 & RDES3_CONTEXT_DESCRIPTOR)
> + >> RDES3_CONTEXT_DESCRIPTOR_SHIFT);
> +
> + if (likely(!own && ctxt)) {
> + if ((p->des0 == 0xffffffff) && (p->des1 == 0xffffffff))
> + /* Corrupted value */
> + ret = -EINVAL;
> + else
> + /* A valid Timestamp is ready to be read */
> + ret = 0;
> + }
> +
> + /* Timestamp not ready */
> + return ret;
> +}
> +
> +static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats)
> {
> struct dma_desc *p = (struct dma_desc *)desc;
> + int ret = -EINVAL;
> +
> + /* Get the status from normal w/b descriptor */
> + if (likely(p->des3 & TDES3_RS1V)) {
> + if (likely(p->des1 & RDES1_TIMESTAMP_AVAILABLE)) {
> + int i = 0;
> +
> + /* Check if timestamp is OK from context descriptor */
> + do {
> + ret = dwmac4_rx_check_timestamp(desc);
Here, "desc" is not pointing to next descriptor (ie context
descriptor). Driver should check the context descriptor.
> + if (ret < 0)
> + goto exit;
> + i++;
>
> - return (p->des1 & RDES1_TIMESTAMP_AVAILABLE)
> - >> RDES1_TIMESTAMP_AVAILABLE_SHIFT;
> + } while ((ret == 1) || (i < 10));
> +
> + if (i == 10)
> + ret = -EBUSY;
> + }
> + }
> +exit:
> + return ret;
> }
>
> static void dwmac4_rd_init_rx_desc(struct dma_desc *p, int disable_rx_ic,
> @@ -373,8 +419,8 @@ const struct stmmac_desc_ops dwmac4_desc_ops = {
> .get_rx_frame_len = dwmac4_wrback_get_rx_frame_len,
> .enable_tx_timestamp = dwmac4_rd_enable_tx_timestamp,
> .get_tx_timestamp_status = dwmac4_wrback_get_tx_timestamp_status,
> - .get_timestamp = dwmac4_wrback_get_timestamp,
> - .get_rx_timestamp_status = dwmac4_context_get_rx_timestamp_status,
> + .get_rx_timestamp_status = dwmac4_wrback_get_rx_timestamp_status,
> + .get_timestamp = dwmac4_get_timestamp,
> .set_tx_ic = dwmac4_rd_set_tx_ic,
> .prepare_tx_desc = dwmac4_rd_prepare_tx_desc,
> .prepare_tso_tx_desc = dwmac4_rd_prepare_tso_tx_desc,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
> index 0902a2e..9736c50 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
> @@ -59,10 +59,13 @@
> #define TDES3_CTXT_TCMSSV BIT(26)
>
> /* TDES3 Common */
> +#define TDES3_RS1V BIT(26)
> +#define TDES3_RS1V_SHIFT 26
> #define TDES3_LAST_DESCRIPTOR BIT(28)
> #define TDES3_LAST_DESCRIPTOR_SHIFT 28
> #define TDES3_FIRST_DESCRIPTOR BIT(29)
> #define TDES3_CONTEXT_TYPE BIT(30)
> +#define TDES3_CONTEXT_TYPE_SHIFT 30
>
> /* TDS3 use for both format (read and write back) */
> #define TDES3_OWN BIT(31)
> @@ -117,6 +120,7 @@
> #define RDES3_LAST_DESCRIPTOR BIT(28)
> #define RDES3_FIRST_DESCRIPTOR BIT(29)
> #define RDES3_CONTEXT_DESCRIPTOR BIT(30)
> +#define RDES3_CONTEXT_DESCRIPTOR_SHIFT 30
>
> /* RDES3 (read format) */
> #define RDES3_BUFFER1_VALID_ADDR BIT(24)
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> index b15fc55..4d2a759 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> @@ -129,6 +129,7 @@ struct stmmac_priv {
> int irq_wake;
> spinlock_t ptp_lock;
> void __iomem *mmcaddr;
> + void __iomem *ptpaddr;
> u32 rx_tail_addr;
> u32 tx_tail_addr;
> u32 mss;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
> index a77f689..10d6059 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
> @@ -34,21 +34,29 @@ static void stmmac_config_hw_tstamping(void __iomem *ioaddr, u32 data)
> }
>
> static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr,
> - u32 ptp_clock)
> + u32 ptp_clock, int gmac4)
> {
> u32 value = readl(ioaddr + PTP_TCR);
> unsigned long data;
>
> - /* Convert the ptp_clock to nano second
> - * formula = (2/ptp_clock) * 1000000000
> - * where, ptp_clock = 50MHz.
> + /* For GMAC3.x, 4.x versions, convert the ptp_clock to nano second
> + * formula = (1/ptp_clock) * 1000000000
> + * where ptp_clock is 50MHz if fine method is used to update system
> */
> - data = (2000000000ULL / ptp_clock);
> + if (value & PTP_TCR_TSCFUPDT)
> + data = (1000000000ULL / 50000000);
> + else
> + data = (1000000000ULL / ptp_clock);
>
> /* 0.465ns accuracy */
> if (!(value & PTP_TCR_TSCTRLSSR))
> data = (data * 1000) / 465;
>
> + data &= PTP_SSIR_SSINC_MASK;
> +
> + if (gmac4)
> + data = data << GMAC4_PTP_SSIR_SSINC_SHIFT;
> +
> writel(data, ioaddr + PTP_SSIR);
>
> return data;
> @@ -104,14 +112,30 @@ static int stmmac_config_addend(void __iomem *ioaddr, u32 addend)
> }
>
> static int stmmac_adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec,
> - int add_sub)
> + int add_sub, int gmac4)
> {
> u32 value;
> int limit;
>
> + if (add_sub) {
> + /* If the new sec value needs to be subtracted with
> + * the system time, then MAC_STSUR reg should be
> + * programmed with (2^32 – <new_sec_value>)
> + */
> + if (gmac4)
> + sec = (100000000ULL - sec);
> +
> + value = readl(ioaddr + PTP_TCR);
> + if (value & PTP_TCR_TSCTRLSSR)
> + nsec = (PTP_DIGITAL_ROLLOVER_MODE - nsec);
> + else
> + nsec = (PTP_BINARY_ROLLOVER_MODE - nsec);
> + }
> +
> writel(sec, ioaddr + PTP_STSUR);
> - writel(((add_sub << PTP_STNSUR_ADDSUB_SHIFT) | nsec),
> - ioaddr + PTP_STNSUR);
> + value = (add_sub << PTP_STNSUR_ADDSUB_SHIFT) | nsec;
> + writel(value, ioaddr + PTP_STNSUR);
> +
> /* issue command to initialize the system time value */
> value = readl(ioaddr + PTP_TCR);
> value |= PTP_TCR_TSUPDT;
> @@ -134,8 +158,9 @@ static u64 stmmac_get_systime(void __iomem *ioaddr)
> {
> u64 ns;
>
> + /* Get the TSSS value */
> ns = readl(ioaddr + PTP_STNSR);
> - /* convert sec time value to nanosecond */
> + /* Get the TSS and convert sec time value to nanosecond */
> ns += readl(ioaddr + PTP_STSR) * 1000000000ULL;
>
> return ns;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 48e71fa..2e228d5 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -340,18 +340,17 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
>
> /* stmmac_get_tx_hwtstamp - get HW TX timestamps
> * @priv: driver private structure
> - * @entry : descriptor index to be used.
> + * @p : descriptor pointer
> * @skb : the socket buffer
> * Description :
> * This function will read timestamp from the descriptor & pass it to stack.
> * and also perform some sanity checks.
> */
> static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv,
> - unsigned int entry, struct sk_buff *skb)
> + struct dma_desc *p, struct sk_buff *skb)
> {
> struct skb_shared_hwtstamps shhwtstamp;
> u64 ns;
> - void *desc = NULL;
>
> if (!priv->hwts_tx_en)
> return;
> @@ -360,58 +359,55 @@ static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv,
> if (likely(!skb || !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)))
> return;
>
> - if (priv->adv_ts)
> - desc = (priv->dma_etx + entry);
> - else
> - desc = (priv->dma_tx + entry);
> -
> /* check tx tstamp status */
> - if (!priv->hw->desc->get_tx_timestamp_status((struct dma_desc *)desc))
> - return;
> + if (!priv->hw->desc->get_tx_timestamp_status(p)) {
> + /* get the valid tstamp */
> + ns = priv->hw->desc->get_timestamp(p, priv->adv_ts);
>
> - /* get the valid tstamp */
> - ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts);
> + memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
> + shhwtstamp.hwtstamp = ns_to_ktime(ns);
>
> - memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
> - shhwtstamp.hwtstamp = ns_to_ktime(ns);
> - /* pass tstamp to stack */
> - skb_tstamp_tx(skb, &shhwtstamp);
> + netdev_info(priv->dev, "get valid TX hw timestamp %llu\n", ns);
> + /* pass tstamp to stack */
> + skb_tstamp_tx(skb, &shhwtstamp);
> + }
>
> return;
> }
>
> /* stmmac_get_rx_hwtstamp - get HW RX timestamps
> * @priv: driver private structure
> - * @entry : descriptor index to be used.
> + * @p : descriptor pointer
> + * @np : next descriptor pointer
> * @skb : the socket buffer
> * Description :
> * This function will read received packet's timestamp from the descriptor
> * and pass it to stack. It also perform some sanity checks.
> */
> -static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv,
> - unsigned int entry, struct sk_buff *skb)
> +static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p,
> + struct dma_desc *np, struct sk_buff *skb)
> {
> struct skb_shared_hwtstamps *shhwtstamp = NULL;
> u64 ns;
> - void *desc = NULL;
>
> if (!priv->hwts_rx_en)
> return;
>
> - if (priv->adv_ts)
> - desc = (priv->dma_erx + entry);
> - else
> - desc = (priv->dma_rx + entry);
> -
> - /* exit if rx tstamp is not valid */
> - if (!priv->hw->desc->get_rx_timestamp_status(desc, priv->adv_ts))
> - return;
> + /* Check if timestamp is available */
> + if (!priv->hw->desc->get_rx_timestamp_status(p, priv->adv_ts)) {
> + /* For GMAC4, the valid timestamp is from CTX next desc. */
> + if (priv->plat->has_gmac4)
> + ns = priv->hw->desc->get_timestamp(np, priv->adv_ts);
> + else
> + ns = priv->hw->desc->get_timestamp(p, priv->adv_ts);
>
> - /* get valid tstamp */
> - ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts);
> - shhwtstamp = skb_hwtstamps(skb);
> - memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
> - shhwtstamp->hwtstamp = ns_to_ktime(ns);
> + netdev_info(priv->dev, "get valid RX hw timestamp %llu\n", ns);
> + shhwtstamp = skb_hwtstamps(skb);
> + memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
> + shhwtstamp->hwtstamp = ns_to_ktime(ns);
> + } else {
> + netdev_err(priv->dev, "cannot get RX hw timestamp\n");
> + }
> }
>
> /**
> @@ -598,17 +594,18 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
> priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON;
>
> if (!priv->hwts_tx_en && !priv->hwts_rx_en)
> - priv->hw->ptp->config_hw_tstamping(priv->ioaddr, 0);
> + priv->hw->ptp->config_hw_tstamping(priv->ptpaddr, 0);
> else {
> value = (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | PTP_TCR_TSCTRLSSR |
> tstamp_all | ptp_v2 | ptp_over_ethernet |
> ptp_over_ipv6_udp | ptp_over_ipv4_udp | ts_event_en |
> ts_master_en | snap_type_sel);
> - priv->hw->ptp->config_hw_tstamping(priv->ioaddr, value);
> + priv->hw->ptp->config_hw_tstamping(priv->ptpaddr, value);
>
> /* program Sub Second Increment reg */
> sec_inc = priv->hw->ptp->config_sub_second_increment(
> - priv->ioaddr, priv->clk_ptp_rate);
> + priv->ptpaddr, priv->clk_ptp_rate,
> + priv->plat->has_gmac4);
> temp = div_u64(1000000000ULL, sec_inc);
>
> /* calculate default added value:
> @@ -618,14 +615,14 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
> */
> temp = (u64)(temp << 32);
> priv->default_addend = div_u64(temp, priv->clk_ptp_rate);
> - priv->hw->ptp->config_addend(priv->ioaddr,
> + priv->hw->ptp->config_addend(priv->ptpaddr,
> priv->default_addend);
>
> /* initialize system time */
> ktime_get_real_ts64(&now);
>
> /* lower 32 bits of tv_sec are safe until y2106 */
> - priv->hw->ptp->init_systime(priv->ioaddr, (u32)now.tv_sec,
> + priv->hw->ptp->init_systime(priv->ptpaddr, (u32)now.tv_sec,
> now.tv_nsec);
> }
>
> @@ -1333,7 +1330,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv)
> priv->dev->stats.tx_packets++;
> priv->xstats.tx_pkt_n++;
> }
> - stmmac_get_tx_hwtstamp(priv, entry, skb);
> + stmmac_get_tx_hwtstamp(priv, p, skb);
> }
>
> if (likely(priv->tx_skbuff_dma[entry].buf)) {
> @@ -1479,10 +1476,13 @@ static void stmmac_mmc_setup(struct stmmac_priv *priv)
> unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET |
> MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET;
>
> - if (priv->synopsys_id >= DWMAC_CORE_4_00)
> + if (priv->synopsys_id >= DWMAC_CORE_4_00) {
> + priv->ptpaddr = priv->ioaddr + PTP_GMAC4_OFFSET;
> priv->mmcaddr = priv->ioaddr + MMC_GMAC4_OFFSET;
> - else
> + } else {
> + priv->ptpaddr = priv->ioaddr + PTP_GMAC3_X_OFFSET;
> priv->mmcaddr = priv->ioaddr + MMC_GMAC3_X_OFFSET;
> + }
>
> dwmac_mmc_intr_all_mask(priv->mmcaddr);
>
> @@ -2477,7 +2477,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
> if (netif_msg_rx_status(priv)) {
> void *rx_head;
>
> - pr_debug("%s: descriptor ring:\n", __func__);
> + pr_info(">>>>>> %s: descriptor ring:\n", __func__);
> if (priv->extend_desc)
> rx_head = (void *)priv->dma_erx;
> else
> @@ -2488,6 +2488,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
> while (count < limit) {
> int status;
> struct dma_desc *p;
> + struct dma_desc *np;
>
> if (priv->extend_desc)
> p = (struct dma_desc *)(priv->dma_erx + entry);
> @@ -2507,9 +2508,11 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
> next_entry = priv->cur_rx;
>
> if (priv->extend_desc)
> - prefetch(priv->dma_erx + next_entry);
> + np = (struct dma_desc *)(priv->dma_erx + next_entry);
> else
> - prefetch(priv->dma_rx + next_entry);
> + np = priv->dma_rx + next_entry;
> +
> + prefetch(np);
>
> if ((priv->extend_desc) && (priv->hw->desc->rx_extended_status))
> priv->hw->desc->rx_extended_status(&priv->dev->stats,
> @@ -2561,7 +2564,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
> frame_len -= ETH_FCS_LEN;
>
> if (netif_msg_rx_status(priv)) {
> - pr_debug("\tdesc: %p [entry %d] buff=0x%x\n",
> + pr_info("\tdesc: %p [entry %d] buff=0x%x\n",
> p, entry, des);
> if (frame_len > ETH_FRAME_LEN)
> pr_debug("\tframe size %d, COE: %d\n",
> @@ -2618,13 +2621,13 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
> DMA_FROM_DEVICE);
> }
>
> - stmmac_get_rx_hwtstamp(priv, entry, skb);
> -
> if (netif_msg_pktdata(priv)) {
> pr_debug("frame received (%dbytes)", frame_len);
> print_pkt(skb->data, frame_len);
> }
>
> + stmmac_get_rx_hwtstamp(priv, p, np, skb);
> +
> stmmac_rx_vlan(priv->dev, skb);
>
> skb->protocol = eth_type_trans(skb, priv->dev);
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
> index 1477471..3eb281d 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
> @@ -54,7 +54,7 @@ static int stmmac_adjust_freq(struct ptp_clock_info *ptp, s32 ppb)
>
> spin_lock_irqsave(&priv->ptp_lock, flags);
>
> - priv->hw->ptp->config_addend(priv->ioaddr, addend);
> + priv->hw->ptp->config_addend(priv->ptpaddr, addend);
>
> spin_unlock_irqrestore(&priv->ptp_lock, flags);
>
> @@ -89,7 +89,8 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
>
> spin_lock_irqsave(&priv->ptp_lock, flags);
>
> - priv->hw->ptp->adjust_systime(priv->ioaddr, sec, nsec, neg_adj);
> + priv->hw->ptp->adjust_systime(priv->ptpaddr, sec, nsec, neg_adj,
> + priv->plat->has_gmac4);
>
> spin_unlock_irqrestore(&priv->ptp_lock, flags);
>
> @@ -114,7 +115,7 @@ static int stmmac_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts)
>
> spin_lock_irqsave(&priv->ptp_lock, flags);
>
> - ns = priv->hw->ptp->get_systime(priv->ioaddr);
> + ns = priv->hw->ptp->get_systime(priv->ptpaddr);
>
> spin_unlock_irqrestore(&priv->ptp_lock, flags);
>
> @@ -141,7 +142,7 @@ static int stmmac_set_time(struct ptp_clock_info *ptp,
>
> spin_lock_irqsave(&priv->ptp_lock, flags);
>
> - priv->hw->ptp->init_systime(priv->ioaddr, ts->tv_sec, ts->tv_nsec);
> + priv->hw->ptp->init_systime(priv->ptpaddr, ts->tv_sec, ts->tv_nsec);
>
> spin_unlock_irqrestore(&priv->ptp_lock, flags);
>
> --
> 2.7.4
>
--
wwr
Rayagond
^ permalink raw reply
* Re: [PATCHv2 iproute2 net-next] tc: m_mirred: Fix parsing of 'index' optional argument
From: Phil Sutter @ 2016-10-27 9:46 UTC (permalink / raw)
To: Shmulik Ladkani; +Cc: Stephen Hemminger, Jamal Hadi Salim, netdev
In-Reply-To: <20161027073606.6112-1-shmulik.ladkani@gmail.com>
Hi,
On Thu, Oct 27, 2016 at 10:36:06AM +0300, Shmulik Ladkani wrote:
> Code in parse_mirred() suggests "index" argument can be placed either
> after the egress/ingress clause, or as the first argument (after
> "action mirred").
>
> However, parse_direction() fails to correctly parse "index" if it's the
> first argument.
>
> For example:
>
> # tc filter add ... action mirred index 5
> RTNETLINK answers: Invalid argument
> (unnecessary RTNETLINK issued, should have been parse error)
>
> # tc filter add ... action mirred index 5 egress redirect dev eth0
> bad action type egress
> (should have been parsed successfully)
According to the action's help text (and the man page which is based
upon that), this behaviour is perfectly fine:
| Usage: mirred <DIRECTION> <ACTION> [index INDEX] <dev DEVICENAME>
So first argument *must* be the direction, second one *must* be the
action, then an optional index and the last one *must* be the interface.
While I don't see a problem with changing that (apart from that I don't
think it's necessary), if you change it you should adjust help text and
man page accordingly.
But is all this really worth it? And if so, why not fix the parser for
good by delaying the whole validation (apart from double arg detection)
until after the parsing itself?
Cheers, Phil
^ permalink raw reply
* [PATCH net] arch/powerpc: Update parameters for csum_tcpudp_magic & csum_tcpudp_nofold
From: Ivan Vecera @ 2016-10-27 14:30 UTC (permalink / raw)
To: netdev; +Cc: Alexander Duyck
Commit 01cfbad "ipv4: Update parameters for csum_tcpudp_magic to their
original types" changed parameters for csum_tcpudp_magic and
csum_tcpudp_nofold for many platforms but not for PowerPC.
Fixes: 01cfbad "ipv4: Update parameters for csum_tcpudp_magic to their original types"
Cc: Alexander Duyck <aduyck@mirantis.com>
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
---
arch/powerpc/include/asm/checksum.h | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h
index ee655ed..1e8fceb 100644
--- a/arch/powerpc/include/asm/checksum.h
+++ b/arch/powerpc/include/asm/checksum.h
@@ -53,10 +53,8 @@ static inline __sum16 csum_fold(__wsum sum)
return (__force __sum16)(~((__force u32)sum + tmp) >> 16);
}
-static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum)
+static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
#ifdef __powerpc64__
unsigned long s = (__force u32)sum;
@@ -83,10 +81,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
-static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum)
+static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
}
--
2.7.3
^ permalink raw reply related
* Re: [PATCH] net: smsc911x: Synchronize the runtime PM status during system suspend
From: Ulf Hansson @ 2016-10-27 11:53 UTC (permalink / raw)
To: Geert Uytterhoeven, Rafael J. Wysocki
Cc: Alan Stern, Linux PM list, netdev@vger.kernel.org, Len Brown,
Pavel Machek, Kevin Hilman, Lina Iyer, Jon Hunter,
Marek Szyprowski, Linus Walleij, Steve Glendinning
In-Reply-To: <CAMuHMdUbU07t2kB6J0rSOiOTbDkegP73FAAEenViuDjQUFE-Jg@mail.gmail.com>
On 27 October 2016 at 13:41, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> Hi Ulf,
>
> On Thu, Oct 27, 2016 at 1:23 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>> The smsc911c driver puts its device into low power state when entering
>> system suspend. Although it doesn't update the device's runtime PM status
>> to RPM_SUSPENDED, which causes problems for a parent device.
>>
>> In particular, when the runtime PM status of the parent is requested to be
>> updated to RPM_SUSPENDED, the runtime PM core prevent this, because it's
>> forbidden to runtime suspend a device, which has an active child.
>>
>> Fix this by updating the runtime PM status of the smsc911x device to
>> RPM_SUSPENDED during system suspend. In system resume, let's reverse that
>> action by runtime resuming the device and thus also the parent.
>
> Thanks for your patch!
>
> The changelog sounds quite innocent, but this does fix a system crash
> during resume from s2ram.
>
>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
>> Cc: Steve Glendinning <steve.glendinning@shawell.net>
>> Fixes: 8b1107b85efd ("PM / Runtime: Don't allow to suspend a device with an active child")
>
> While the abovementioned commit made the problem visible, the root cause
> was present before, right?
Yes.
>
>> ---
>>
>> Note that the commit this change fixes is currently queued for 4.10 via
>> Rafael's linux-pm tree. So this fix should go via that tree as well.
>
> Alternatively, this could go in in v4.9 to avoid the problem from ever
> appearing in upstream?
Makes perfect sense! In that case we should remove the fixes tag.
Rafael, can you pick this up for 4.9 rc[n]?
Kind regards
Uffe
^ permalink raw reply
* [patch net-next 0/5] mlxsw: small driver update
From: Jiri Pirko @ 2016-10-27 13:12 UTC (permalink / raw)
To: netdev; +Cc: davem, idosch, eladr, yotamg, nogahf, ogerlitz
From: Jiri Pirko <jiri@mellanox.com>
For details, see individual patches.
Ido Schimmel (1):
mlxsw: spectrum: Remove extra whitespace
Jiri Pirko (4):
mlxsw: pci: Rename header with HW definitions
mlxsw: Move PCI id table definitions into driver modules
mlxsw: spectrum: Set physical device for port netdevice
mlxsw: switchx2: Set physical device for port netdevice
drivers/net/ethernet/mellanox/mlxsw/Kconfig | 4 +-
drivers/net/ethernet/mellanox/mlxsw/core.c | 14 --
drivers/net/ethernet/mellanox/mlxsw/core.h | 8 -
drivers/net/ethernet/mellanox/mlxsw/pci.c | 56 ++---
drivers/net/ethernet/mellanox/mlxsw/pci.h | 206 ++----------------
drivers/net/ethernet/mellanox/mlxsw/pci_hw.h | 229 +++++++++++++++++++++
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 26 ++-
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 2 +-
drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 35 +++-
9 files changed, 323 insertions(+), 257 deletions(-)
create mode 100644 drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
--
2.5.5
^ permalink raw reply
* [patch net-next 1/5] mlxsw: spectrum: Remove extra whitespace
From: Jiri Pirko @ 2016-10-27 13:12 UTC (permalink / raw)
To: netdev; +Cc: davem, idosch, eladr, yotamg, nogahf, ogerlitz
In-Reply-To: <1477573981-26546-1-git-send-email-jiri@resnulli.us>
From: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 113f667..107934f 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -1980,7 +1980,7 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
if (err)
goto err_vrs_init;
- err = mlxsw_sp_neigh_init(mlxsw_sp);
+ err = mlxsw_sp_neigh_init(mlxsw_sp);
if (err)
goto err_neigh_init;
--
2.5.5
^ permalink raw reply related
* Re: [PATCHv2 iproute2 net-next] tc: m_mirred: Fix parsing of 'index' optional argument
From: Shmulik Ladkani @ 2016-10-27 14:22 UTC (permalink / raw)
To: Phil Sutter; +Cc: Stephen Hemminger, Jamal Hadi Salim, netdev
In-Reply-To: <20161027094633.GR5640@orbyte.nwl.cc>
Hi Phil,
On Thu, 27 Oct 2016 11:46:33 +0200, phil@nwl.cc wrote:
> According to the action's help text (and the man page which is based
> upon that), this behaviour is perfectly fine:
>
> | Usage: mirred <DIRECTION> <ACTION> [index INDEX] <dev DEVICENAME>
>
> So first argument *must* be the direction, second one *must* be the
> action, then an optional index and the last one *must* be the interface.
There is an inconsistency betweem man/help and code.
Actual code, since first committed, attempts to parse "index" as 1st
argument (without success), see parse_mirred():
if (matches(*argv, "egress") == 0 || matches(*argv, "index") == 0) {
int ret = parse_egress(a, &argc, &argv, tca_id, n);
> While I don't see a problem with changing that (apart from that I don't
> think it's necessary)
Not "changing" per-se, but rather "fixing", at least according code
author's intention :)
As I suggested in the notes part of the commit log,
>> An alternative solution: banning "index" as 1st argument in parse_mirred
I ok with removing the code trying to support "index" as 1st argument as
well.
I only assumed one might want this behaviour due to intention expressed
by original code.
^ permalink raw reply
* [PATCH net-next v1 16/16] tipc: remove SS_CONNECTED sock state
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
In this commit, we remove the state SS_CONNECTED and replace it
with the function tipc_sk_state_connected() wherever possible.
A socket with sk_state TIPC_ESTABLISHED or TIPC_PROBING replaces
the socket state SS_CONNECTED.
After these changes, the sock->state is no longer explicitly used by
tipc. The FSM below is for various types of connection oriented sockets.
Stream Server Listening Socket:
+-----------+ +-------------+
| TIPC_OPEN |------>| TIPC_LISTEN |
+-----------+ +-------------+
|
+--------------+ |
| TIPC_CLOSING |<-----------+
+--------------+
Stream Server Data Socket:
+-----------+ +------------------+
| TIPC_OPEN |------>| TIPC_ESTABLISHED |<---+
+-----------+ +------------------+ |
^ | | |
| | +----------+
| v
+--------------+
| TIPC_PROBING |
+--------------+
|
|
v
+--------------+ +--------------------+
| TIPC_CLOSING |<---| TIPC_DISCONNECTING |
+--------------+ +--------------------+
Stream Socket Client:
+-----------+ +-----------------+
| TIPC_OPEN |------>| TIPC_CONNECTING |
+-----------+ +-----------------+
|
|
v
+------------------+
| TIPC_ESTABLISHED |<---+
+------------------+ |
^ | | |
| | +---------+
| v
+--------------+
| TIPC_PROBING |
+--------------+
|
|
v
+--------------+ +--------------------+
| TIPC_CLOSING |<---| TIPC_DISCONNECTING |
+--------------+ +--------------------+
Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
net/tipc/socket.c | 100 +++++++++++++++++++++++++-----------------------------
1 file changed, 47 insertions(+), 53 deletions(-)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 7702acf0bfab..2a095fa6bff7 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -286,7 +286,7 @@ static void tsk_rej_rx_queue(struct sock *sk)
static bool tipc_sk_connected(struct sock *sk)
{
- return sk->sk_socket->state == SS_CONNECTED;
+ return sk->sk_state == TIPC_ESTABLISHED || sk->sk_state == TIPC_PROBING;
}
/* tipc_sk_type_connectionless - check if the socket is datagram socket
@@ -517,7 +517,7 @@ static int tipc_release(struct socket *sock)
kfree_skb(skb);
else {
if ((sk->sk_state == TIPC_CONNECTING) ||
- (sock->state == SS_CONNECTED)) {
+ tipc_sk_connected(sk)) {
tipc_set_sk_state(sk, TIPC_CLOSING);
tipc_node_remove_conn(net, dnode, tsk->portid);
}
@@ -631,7 +631,7 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
memset(addr, 0, sizeof(*addr));
if (peer) {
- if ((sock->state != SS_CONNECTED) &&
+ if ((!tipc_sk_connected(sk)) &&
((peer != 2) || (sk->sk_state != TIPC_DISCONNECTING)))
return -ENOTCONN;
addr->addr.id.ref = tsk_peer_port(tsk);
@@ -677,30 +677,28 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
sock_poll_wait(file, sk_sleep(sk), wait);
- if ((int)sock->state == SS_CONNECTED) {
+ switch (sk->sk_state) {
+ case TIPC_PROBING:
+ case TIPC_ESTABLISHED:
if (!tsk->link_cong && !tsk_conn_cong(tsk))
mask |= POLLOUT;
+ /* fall thru' */
+ case TIPC_LISTEN:
+ case TIPC_CONNECTING:
if (!skb_queue_empty(&sk->sk_receive_queue))
mask |= (POLLIN | POLLRDNORM);
- } else {
- switch (sk->sk_state) {
- case TIPC_OPEN:
- if (!tsk->link_cong)
- mask |= POLLOUT;
- if (tipc_sk_type_connectionless(sk) &&
- (!skb_queue_empty(&sk->sk_receive_queue)))
- mask |= (POLLIN | POLLRDNORM);
- break;
- case TIPC_CLOSING:
- case TIPC_DISCONNECTING:
- mask = (POLLIN | POLLRDNORM | POLLHUP);
- break;
- case TIPC_LISTEN:
- case TIPC_CONNECTING:
- if (!skb_queue_empty(&sk->sk_receive_queue))
- mask |= (POLLIN | POLLRDNORM);
- break;
- }
+ break;
+ case TIPC_OPEN:
+ if (!tsk->link_cong)
+ mask |= POLLOUT;
+ if (tipc_sk_type_connectionless(sk) &&
+ (!skb_queue_empty(&sk->sk_receive_queue)))
+ mask |= (POLLIN | POLLRDNORM);
+ break;
+ case TIPC_CLOSING:
+ case TIPC_DISCONNECTING:
+ mask = (POLLIN | POLLRDNORM | POLLHUP);
+ break;
}
return mask;
@@ -1034,7 +1032,7 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p)
return err;
if (sk->sk_state == TIPC_DISCONNECTING)
return -EPIPE;
- else if (sock->state != SS_CONNECTED)
+ else if (!tipc_sk_connected(sk))
return -ENOTCONN;
if (!*timeo_p)
return -EAGAIN;
@@ -1101,7 +1099,7 @@ static int __tipc_send_stream(struct socket *sock, struct msghdr *m, size_t dsz)
if (dsz > (uint)INT_MAX)
return -EMSGSIZE;
- if (unlikely(sock->state != SS_CONNECTED)) {
+ if (unlikely(!tipc_sk_connected(sk))) {
if (sk->sk_state == TIPC_DISCONNECTING)
return -EPIPE;
else
@@ -1616,29 +1614,11 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
{
struct sock *sk = &tsk->sk;
struct net *net = sock_net(sk);
- struct socket *sock = sk->sk_socket;
struct tipc_msg *hdr = buf_msg(skb);
if (unlikely(msg_mcast(hdr)))
return false;
- switch ((int)sock->state) {
- case SS_CONNECTED:
-
- /* Accept only connection-based messages sent by peer */
- if (unlikely(!tsk_peer_msg(tsk, hdr)))
- return false;
-
- if (unlikely(msg_errcode(hdr))) {
- tipc_set_sk_state(sk, TIPC_DISCONNECTING);
- /* Let timer expire on it's own */
- tipc_node_remove_conn(net, tsk_peer_node(tsk),
- tsk->portid);
- sk->sk_state_change(sk);
- }
- return true;
- }
-
switch (sk->sk_state) {
case TIPC_CONNECTING:
/* Accept only ACK or NACK message */
@@ -1659,7 +1639,6 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
tipc_sk_finish_conn(tsk, msg_origport(hdr), msg_orignode(hdr));
msg_set_importance(&tsk->phdr, msg_importance(hdr));
- sock->state = SS_CONNECTED;
/* If 'ACK+' message, add to socket receive queue */
if (msg_data_sz(hdr))
@@ -1682,6 +1661,20 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
if (!msg_connected(hdr) && !(msg_errcode(hdr)))
return true;
break;
+ case TIPC_PROBING:
+ case TIPC_ESTABLISHED:
+ /* Accept only connection-based messages sent by peer */
+ if (unlikely(!tsk_peer_msg(tsk, hdr)))
+ return false;
+
+ if (unlikely(msg_errcode(hdr))) {
+ tipc_set_sk_state(sk, TIPC_DISCONNECTING);
+ /* Let timer expire on it's own */
+ tipc_node_remove_conn(net, tsk_peer_node(tsk),
+ tsk->portid);
+ sk->sk_state_change(sk);
+ }
+ return true;
default:
pr_err("Unknown sk_state %u\n", sk->sk_state);
}
@@ -2027,13 +2020,14 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
timeout = msecs_to_jiffies(timeout);
/* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */
res = tipc_wait_for_connect(sock, &timeout);
- goto exit;
- }
-
- if (sock->state == SS_CONNECTED)
+ break;
+ case TIPC_PROBING:
+ case TIPC_ESTABLISHED:
res = -EISCONN;
- else
+ break;
+ default:
res = -EINVAL;
+ }
exit:
release_sock(sk);
@@ -2142,7 +2136,6 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
/* Connect new socket to it's peer */
tipc_sk_finish_conn(new_tsock, msg_origport(msg), msg_orignode(msg));
- new_sock->state = SS_CONNECTED;
tsk_set_importance(new_tsock, msg_importance(msg));
if (msg_named(msg)) {
@@ -2196,7 +2189,10 @@ static int tipc_shutdown(struct socket *sock, int how)
lock_sock(sk);
- if (sock->state == SS_CONNECTED || sk->sk_state == TIPC_CONNECTING) {
+ switch (sk->sk_state) {
+ case TIPC_PROBING:
+ case TIPC_CONNECTING:
+ case TIPC_ESTABLISHED:
restart:
dnode = tsk_peer_node(tsk);
@@ -2219,9 +2215,7 @@ static int tipc_shutdown(struct socket *sock, int how)
}
tipc_set_sk_state(sk, TIPC_DISCONNECTING);
tipc_node_remove_conn(net, dnode, tsk->portid);
- }
- switch (sk->sk_state) {
case TIPC_DISCONNECTING:
/* Discard any unreceived messages */
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 15/16] tipc: create TIPC_CONNECTING as a new sk_state
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
In this commit, we create a new tipc socket state TIPC_CONNECTING
by primarily replacing the SS_CONNECTING with TIPC_CONNECTING.
There is no functional change in this commit.
Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
include/uapi/linux/tipc.h | 1 +
net/tipc/socket.c | 61 ++++++++++++++++++++++-------------------------
2 files changed, 29 insertions(+), 33 deletions(-)
diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
index a45ebf273e76..f2d9294d0920 100644
--- a/include/uapi/linux/tipc.h
+++ b/include/uapi/linux/tipc.h
@@ -186,6 +186,7 @@ enum {
TIPC_OPEN,
TIPC_DISCONNECTING,
TIPC_CLOSING,
+ TIPC_CONNECTING,
};
/*
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index cddf9bca9a90..7702acf0bfab 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -342,7 +342,6 @@ static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
*/
static int tipc_set_sk_state(struct sock *sk, int state)
{
- int oldstate = sk->sk_socket->state;
int oldsk_state = sk->sk_state;
int res = -EINVAL;
@@ -352,6 +351,7 @@ static int tipc_set_sk_state(struct sock *sk, int state)
res = 0;
break;
case TIPC_LISTEN:
+ case TIPC_CONNECTING:
if (oldsk_state == TIPC_OPEN)
res = 0;
break;
@@ -366,7 +366,7 @@ static int tipc_set_sk_state(struct sock *sk, int state)
case TIPC_DISCONNECTING:
if (oldsk_state == TIPC_PROBING ||
oldsk_state == TIPC_ESTABLISHED ||
- oldstate == SS_CONNECTING)
+ oldsk_state == TIPC_CONNECTING)
res = 0;
break;
}
@@ -516,7 +516,7 @@ static int tipc_release(struct socket *sock)
if (TIPC_SKB_CB(skb)->bytes_read)
kfree_skb(skb);
else {
- if ((sock->state == SS_CONNECTING) ||
+ if ((sk->sk_state == TIPC_CONNECTING) ||
(sock->state == SS_CONNECTED)) {
tipc_set_sk_state(sk, TIPC_CLOSING);
tipc_node_remove_conn(net, dnode, tsk->portid);
@@ -677,16 +677,12 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
sock_poll_wait(file, sk_sleep(sk), wait);
- switch ((int)sock->state) {
- case SS_CONNECTED:
+ if ((int)sock->state == SS_CONNECTED) {
if (!tsk->link_cong && !tsk_conn_cong(tsk))
mask |= POLLOUT;
- /* fall thru' */
- case SS_CONNECTING:
if (!skb_queue_empty(&sk->sk_receive_queue))
mask |= (POLLIN | POLLRDNORM);
- break;
- default:
+ } else {
switch (sk->sk_state) {
case TIPC_OPEN:
if (!tsk->link_cong)
@@ -700,6 +696,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
mask = (POLLIN | POLLRDNORM | POLLHUP);
break;
case TIPC_LISTEN:
+ case TIPC_CONNECTING:
if (!skb_queue_empty(&sk->sk_receive_queue))
mask |= (POLLIN | POLLRDNORM);
break;
@@ -1004,7 +1001,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
rc = tipc_node_xmit(net, &pktchain, dnode, tsk->portid);
if (likely(!rc)) {
if (!is_connectionless)
- sock->state = SS_CONNECTING;
+ tipc_set_sk_state(sk, TIPC_CONNECTING);
return dsz;
}
if (rc == -ELINKCONG) {
@@ -1640,9 +1637,10 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
sk->sk_state_change(sk);
}
return true;
+ }
- case SS_CONNECTING:
-
+ switch (sk->sk_state) {
+ case TIPC_CONNECTING:
/* Accept only ACK or NACK message */
if (unlikely(!msg_connected(hdr)))
return false;
@@ -1674,9 +1672,7 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
/* 'ACK-' message is neither accepted nor rejected: */
msg_set_dest_droppable(hdr, 1);
return false;
- }
- switch (sk->sk_state) {
case TIPC_OPEN:
case TIPC_CLOSING:
case TIPC_DISCONNECTING:
@@ -1946,7 +1942,8 @@ static int tipc_wait_for_connect(struct socket *sock, long *timeo_p)
return sock_intr_errno(*timeo_p);
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
- done = sk_wait_event(sk, timeo_p, sock->state != SS_CONNECTING);
+ done = sk_wait_event(sk, timeo_p,
+ sk->sk_state != TIPC_CONNECTING);
finish_wait(sk_sleep(sk), &wait);
} while (!done);
return 0;
@@ -1969,7 +1966,7 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest;
struct msghdr m = {NULL,};
long timeout = (flags & O_NONBLOCK) ? 0 : tsk->conn_timeout;
- socket_state previous;
+ int previous;
int res = 0;
lock_sock(sk);
@@ -1997,7 +1994,7 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
goto exit;
}
- previous = sock->state;
+ previous = sk->sk_state;
switch (sk->sk_state) {
case TIPC_OPEN:
@@ -2015,31 +2012,29 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
if ((res < 0) && (res != -EWOULDBLOCK))
goto exit;
- /* Just entered SS_CONNECTING state; the only
+ /* Just entered TIPC_CONNECTING state; the only
* difference is that return value in non-blocking
* case is EINPROGRESS, rather than EALREADY.
*/
res = -EINPROGRESS;
- break;
- }
-
- switch (sock->state) {
- case SS_CONNECTING:
- if (previous == SS_CONNECTING)
- res = -EALREADY;
- if (!timeout)
+ /* fall thru' */
+ case TIPC_CONNECTING:
+ if (!timeout) {
+ if (previous == TIPC_CONNECTING)
+ res = -EALREADY;
goto exit;
+ }
timeout = msecs_to_jiffies(timeout);
/* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */
res = tipc_wait_for_connect(sock, &timeout);
- break;
- case SS_CONNECTED:
+ goto exit;
+ }
+
+ if (sock->state == SS_CONNECTED)
res = -EISCONN;
- break;
- default:
+ else
res = -EINVAL;
- break;
- }
+
exit:
release_sock(sk);
return res;
@@ -2201,7 +2196,7 @@ static int tipc_shutdown(struct socket *sock, int how)
lock_sock(sk);
- if (sock->state == SS_CONNECTING || sock->state == SS_CONNECTED) {
+ if (sock->state == SS_CONNECTED || sk->sk_state == TIPC_CONNECTING) {
restart:
dnode = tsk_peer_node(tsk);
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 14/16] tipc: create TIPC_CLOSING as a new sk_state
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
In this commit, we create a new tipc socket state TIPC_CLOSING in
sk_state. We primarily replace all the remaining references to
SS_DISCONNECTING sock->state with TIPC_CLOSING. Thus the FSM for
sockets will be as follows:
For connectionless sockets:
+-----------+ +--------------+
| TIPC_OPEN |------>| TIPC_CLOSING |
+-----------+ +--------------+
For connection oriented sockets:
+-----------+ +------------------+ +--------------+
| TIPC_OPEN |------>| TIPC_XXXX (1..N) |----->| TIPC_CLOSING |
+-----------+ +------------------+ +--------------+
There is no functional change in this commit.
Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
include/uapi/linux/tipc.h | 1 +
net/tipc/socket.c | 19 ++++++++-----------
2 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
index f5c03fdfc8a8..a45ebf273e76 100644
--- a/include/uapi/linux/tipc.h
+++ b/include/uapi/linux/tipc.h
@@ -185,6 +185,7 @@ enum {
TIPC_ESTABLISHED,
TIPC_OPEN,
TIPC_DISCONNECTING,
+ TIPC_CLOSING,
};
/*
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 6fef087c4aac..cddf9bca9a90 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -348,6 +348,7 @@ static int tipc_set_sk_state(struct sock *sk, int state)
switch (state) {
case TIPC_OPEN:
+ case TIPC_CLOSING:
res = 0;
break;
case TIPC_LISTEN:
@@ -508,7 +509,7 @@ static int tipc_release(struct socket *sock)
* (which disconnects locally & sends a 'FIN+' to peer)
*/
dnode = tsk_peer_node(tsk);
- while (sock->state != SS_DISCONNECTING) {
+ while (sk->sk_state != TIPC_CLOSING) {
skb = __skb_dequeue(&sk->sk_receive_queue);
if (skb == NULL)
break;
@@ -517,7 +518,7 @@ static int tipc_release(struct socket *sock)
else {
if ((sock->state == SS_CONNECTING) ||
(sock->state == SS_CONNECTED)) {
- sock->state = SS_DISCONNECTING;
+ tipc_set_sk_state(sk, TIPC_CLOSING);
tipc_node_remove_conn(net, dnode, tsk->portid);
}
tipc_sk_respond(sk, skb, TIPC_ERR_NO_PORT);
@@ -538,7 +539,7 @@ static int tipc_release(struct socket *sock)
}
/* Reject any messages that accumulated in backlog queue */
- sock->state = SS_DISCONNECTING;
+ tipc_set_sk_state(sk, TIPC_CLOSING);
release_sock(sk);
call_rcu(&tsk->rcu, tipc_sk_callback);
@@ -685,9 +686,6 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
if (!skb_queue_empty(&sk->sk_receive_queue))
mask |= (POLLIN | POLLRDNORM);
break;
- case SS_DISCONNECTING:
- mask = (POLLIN | POLLRDNORM | POLLHUP);
- break;
default:
switch (sk->sk_state) {
case TIPC_OPEN:
@@ -697,6 +695,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
(!skb_queue_empty(&sk->sk_receive_queue)))
mask |= (POLLIN | POLLRDNORM);
break;
+ case TIPC_CLOSING:
case TIPC_DISCONNECTING:
mask = (POLLIN | POLLRDNORM | POLLHUP);
break;
@@ -881,7 +880,7 @@ static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p)
int err = sock_error(sk);
if (err)
return err;
- if (sock->state == SS_DISCONNECTING)
+ if (sk->sk_state == TIPC_CLOSING)
return -EPIPE;
if (!*timeo_p)
return -EAGAIN;
@@ -1334,7 +1333,7 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
for (;;) {
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
if (timeo && skb_queue_empty(&sk->sk_receive_queue)) {
- if (sock->state == SS_DISCONNECTING) {
+ if (sk->sk_state == TIPC_CLOSING) {
err = -ENOTCONN;
break;
}
@@ -1675,13 +1674,11 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
/* 'ACK-' message is neither accepted nor rejected: */
msg_set_dest_droppable(hdr, 1);
return false;
-
- case SS_DISCONNECTING:
- break;
}
switch (sk->sk_state) {
case TIPC_OPEN:
+ case TIPC_CLOSING:
case TIPC_DISCONNECTING:
break;
case TIPC_LISTEN:
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 13/16] tipc: create TIPC_DISCONNECTING as a new sk_state
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
In this commit, we create a new tipc socket state TIPC_DISCONNECTING in
sk_state. TIPC_DISCONNECTING is replacing the socket connection status
update using SS_DISCONNECTING.
TIPC_DISCONNECTING is set for connection oriented sockets at:
- tipc_shutdown()
- connection probe timeout
- when we receive an error message on the connection.
There is no functional change in this commit.
Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
include/uapi/linux/tipc.h | 1 +
net/tipc/socket.c | 39 +++++++++++++++++++++++----------------
2 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
index ae45de5e0d93..f5c03fdfc8a8 100644
--- a/include/uapi/linux/tipc.h
+++ b/include/uapi/linux/tipc.h
@@ -184,6 +184,7 @@ enum {
TIPC_PROBING,
TIPC_ESTABLISHED,
TIPC_OPEN,
+ TIPC_DISCONNECTING,
};
/*
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index da7f7e8244f2..6fef087c4aac 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -359,10 +359,13 @@ static int tipc_set_sk_state(struct sock *sk, int state)
res = 0;
break;
case TIPC_ESTABLISHED:
+ if (oldsk_state == TIPC_OPEN)
+ res = 0;
+ /* fall thru' */
+ case TIPC_DISCONNECTING:
if (oldsk_state == TIPC_PROBING ||
oldsk_state == TIPC_ESTABLISHED ||
- oldstate == SS_CONNECTING ||
- oldsk_state == TIPC_OPEN)
+ oldstate == SS_CONNECTING)
res = 0;
break;
}
@@ -621,13 +624,14 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
int *uaddr_len, int peer)
{
struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
- struct tipc_sock *tsk = tipc_sk(sock->sk);
+ struct sock *sk = sock->sk;
+ struct tipc_sock *tsk = tipc_sk(sk);
struct tipc_net *tn = net_generic(sock_net(sock->sk), tipc_net_id);
memset(addr, 0, sizeof(*addr));
if (peer) {
if ((sock->state != SS_CONNECTED) &&
- ((peer != 2) || (sock->state != SS_DISCONNECTING)))
+ ((peer != 2) || (sk->sk_state != TIPC_DISCONNECTING)))
return -ENOTCONN;
addr->addr.id.ref = tsk_peer_port(tsk);
addr->addr.id.node = tsk_peer_node(tsk);
@@ -693,6 +697,9 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
(!skb_queue_empty(&sk->sk_receive_queue)))
mask |= (POLLIN | POLLRDNORM);
break;
+ case TIPC_DISCONNECTING:
+ mask = (POLLIN | POLLRDNORM | POLLHUP);
+ break;
case TIPC_LISTEN:
if (!skb_queue_empty(&sk->sk_receive_queue))
mask |= (POLLIN | POLLRDNORM);
@@ -1029,7 +1036,7 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p)
int err = sock_error(sk);
if (err)
return err;
- if (sock->state == SS_DISCONNECTING)
+ if (sk->sk_state == TIPC_DISCONNECTING)
return -EPIPE;
else if (sock->state != SS_CONNECTED)
return -ENOTCONN;
@@ -1099,7 +1106,7 @@ static int __tipc_send_stream(struct socket *sock, struct msghdr *m, size_t dsz)
return -EMSGSIZE;
if (unlikely(sock->state != SS_CONNECTED)) {
- if (sock->state == SS_DISCONNECTING)
+ if (sk->sk_state == TIPC_DISCONNECTING)
return -EPIPE;
else
return -ENOTCONN;
@@ -1627,7 +1634,7 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
return false;
if (unlikely(msg_errcode(hdr))) {
- sock->state = SS_DISCONNECTING;
+ tipc_set_sk_state(sk, TIPC_DISCONNECTING);
/* Let timer expire on it's own */
tipc_node_remove_conn(net, tsk_peer_node(tsk),
tsk->portid);
@@ -1642,13 +1649,13 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
return false;
if (unlikely(msg_errcode(hdr))) {
- sock->state = SS_DISCONNECTING;
+ tipc_set_sk_state(sk, TIPC_DISCONNECTING);
sk->sk_err = ECONNREFUSED;
return true;
}
if (unlikely(!msg_isdata(hdr))) {
- sock->state = SS_DISCONNECTING;
+ tipc_set_sk_state(sk, TIPC_DISCONNECTING);
sk->sk_err = EINVAL;
return true;
}
@@ -1675,6 +1682,7 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
switch (sk->sk_state) {
case TIPC_OPEN:
+ case TIPC_DISCONNECTING:
break;
case TIPC_LISTEN:
/* Accept only SYN message */
@@ -2196,9 +2204,7 @@ static int tipc_shutdown(struct socket *sock, int how)
lock_sock(sk);
- switch (sock->state) {
- case SS_CONNECTING:
- case SS_CONNECTED:
+ if (sock->state == SS_CONNECTING || sock->state == SS_CONNECTED) {
restart:
dnode = tsk_peer_node(tsk);
@@ -2219,11 +2225,12 @@ static int tipc_shutdown(struct socket *sock, int how)
if (skb)
tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
}
- sock->state = SS_DISCONNECTING;
+ tipc_set_sk_state(sk, TIPC_DISCONNECTING);
tipc_node_remove_conn(net, dnode, tsk->portid);
- /* fall through */
+ }
- case SS_DISCONNECTING:
+ switch (sk->sk_state) {
+ case TIPC_DISCONNECTING:
/* Discard any unreceived messages */
__skb_queue_purge(&sk->sk_receive_queue);
@@ -2259,7 +2266,7 @@ static void tipc_sk_timeout(unsigned long data)
if (sk->sk_state == TIPC_PROBING) {
if (!sock_owned_by_user(sk)) {
- sk->sk_socket->state = SS_DISCONNECTING;
+ tipc_set_sk_state(sk, TIPC_DISCONNECTING);
tipc_node_remove_conn(sock_net(sk), tsk_peer_node(tsk),
tsk_peer_port(tsk));
sk->sk_state_change(sk);
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 12/16] tipc: create TIPC_OPEN as a new sk_state
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
In this commit, we create a new tipc socket state TIPC_OPEN in
sk_state. We primarily replace the SS_UNCONNECTED sock->state with
TIPC_OPEN.
Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
include/uapi/linux/tipc.h | 1 +
net/tipc/socket.c | 94 ++++++++++++++++++++---------------------------
2 files changed, 41 insertions(+), 54 deletions(-)
diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
index 189bfed0363c..ae45de5e0d93 100644
--- a/include/uapi/linux/tipc.h
+++ b/include/uapi/linux/tipc.h
@@ -183,6 +183,7 @@ enum {
TIPC_LISTEN = 1,
TIPC_PROBING,
TIPC_ESTABLISHED,
+ TIPC_OPEN,
};
/*
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 04d388c063a6..da7f7e8244f2 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -347,8 +347,11 @@ static int tipc_set_sk_state(struct sock *sk, int state)
int res = -EINVAL;
switch (state) {
+ case TIPC_OPEN:
+ res = 0;
+ break;
case TIPC_LISTEN:
- if (oldstate == SS_UNCONNECTED)
+ if (oldsk_state == TIPC_OPEN)
res = 0;
break;
case TIPC_PROBING:
@@ -359,7 +362,7 @@ static int tipc_set_sk_state(struct sock *sk, int state)
if (oldsk_state == TIPC_PROBING ||
oldsk_state == TIPC_ESTABLISHED ||
oldstate == SS_CONNECTING ||
- oldstate == SS_UNCONNECTED)
+ oldsk_state == TIPC_OPEN)
res = 0;
break;
}
@@ -426,8 +429,8 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
/* Finish initializing socket data structures */
sock->ops = ops;
- sock->state = SS_UNCONNECTED;
sock_init_data(sock, sk);
+ tipc_set_sk_state(sk, TIPC_OPEN);
if (tipc_sk_insert(tsk)) {
pr_warn("Socket create failed; port number exhausted\n");
return -EINVAL;
@@ -451,6 +454,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
if (sock->type == SOCK_DGRAM)
tsk_set_unreliable(tsk, true);
}
+
return 0;
}
@@ -655,28 +659,6 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
* exits. TCP and other protocols seem to rely on higher level poll routines
* to handle any preventable race conditions, so TIPC will do the same ...
*
- * TIPC sets the returned events as follows:
- *
- * socket state flags set
- * ------------ ---------
- * unconnected no read flags
- * POLLOUT if port is not congested
- *
- * connecting POLLIN/POLLRDNORM if ACK/NACK in rx queue
- * no write flags
- *
- * connected POLLIN/POLLRDNORM if data in rx queue
- * POLLOUT if port is not congested
- *
- * disconnecting POLLIN/POLLRDNORM/POLLHUP
- * no write flags
- *
- * listening POLLIN if SYN in rx queue
- * no write flags
- *
- * ready POLLIN/POLLRDNORM if data in rx queue
- * [connectionless] POLLOUT (since port cannot be congested)
- *
* IMPORTANT: The fact that a read or write operation is indicated does NOT
* imply that the operation will succeed, merely that it should be performed
* and will not block.
@@ -690,27 +672,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
sock_poll_wait(file, sk_sleep(sk), wait);
- if (tipc_sk_type_connectionless(sk)) {
- if (!tsk->link_cong)
- mask |= POLLOUT;
- if (!skb_queue_empty(&sk->sk_receive_queue))
- mask |= (POLLIN | POLLRDNORM);
- return mask;
- }
-
switch ((int)sock->state) {
- case SS_UNCONNECTED:
- switch (sk->sk_state) {
- case TIPC_LISTEN:
- if (!skb_queue_empty(&sk->sk_receive_queue))
- mask |= (POLLIN | POLLRDNORM);
- break;
- default:
- if (!tsk->link_cong)
- mask |= POLLOUT;
- break;
- }
- break;
case SS_CONNECTED:
if (!tsk->link_cong && !tsk_conn_cong(tsk))
mask |= POLLOUT;
@@ -722,6 +684,20 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
case SS_DISCONNECTING:
mask = (POLLIN | POLLRDNORM | POLLHUP);
break;
+ default:
+ switch (sk->sk_state) {
+ case TIPC_OPEN:
+ if (!tsk->link_cong)
+ mask |= POLLOUT;
+ if (tipc_sk_type_connectionless(sk) &&
+ (!skb_queue_empty(&sk->sk_receive_queue)))
+ mask |= (POLLIN | POLLRDNORM);
+ break;
+ case TIPC_LISTEN:
+ if (!skb_queue_empty(&sk->sk_receive_queue))
+ mask |= (POLLIN | POLLRDNORM);
+ break;
+ }
}
return mask;
@@ -969,7 +945,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
if (!is_connectionless) {
if (sk->sk_state == TIPC_LISTEN)
return -EPIPE;
- if (sock->state != SS_UNCONNECTED)
+ if (sk->sk_state != TIPC_OPEN)
return -EISCONN;
if (tsk->published)
return -EOPNOTSUPP;
@@ -1404,7 +1380,7 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len,
lock_sock(sk);
- if (!is_connectionless && unlikely(sock->state == SS_UNCONNECTED)) {
+ if (!is_connectionless && unlikely(sk->sk_state == TIPC_OPEN)) {
res = -ENOTCONN;
goto exit;
}
@@ -1501,7 +1477,7 @@ static int tipc_recv_stream(struct socket *sock, struct msghdr *m,
lock_sock(sk);
- if (unlikely(sock->state == SS_UNCONNECTED)) {
+ if (unlikely(sk->sk_state == TIPC_OPEN)) {
res = -ENOTCONN;
goto exit;
}
@@ -1693,17 +1669,22 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
msg_set_dest_droppable(hdr, 1);
return false;
- case SS_UNCONNECTED:
+ case SS_DISCONNECTING:
+ break;
+ }
+ switch (sk->sk_state) {
+ case TIPC_OPEN:
+ break;
+ case TIPC_LISTEN:
/* Accept only SYN message */
if (!msg_connected(hdr) && !(msg_errcode(hdr)))
return true;
break;
- case SS_DISCONNECTING:
- break;
default:
- pr_err("Unknown socket state %u\n", sock->state);
+ pr_err("Unknown sk_state %u\n", sk->sk_state);
}
+
return false;
}
@@ -2012,8 +1993,9 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
}
previous = sock->state;
- switch (sock->state) {
- case SS_UNCONNECTED:
+
+ switch (sk->sk_state) {
+ case TIPC_OPEN:
/* Send a 'SYN-' to destination */
m.msg_name = dest;
m.msg_namelen = destlen;
@@ -2033,6 +2015,10 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
* case is EINPROGRESS, rather than EALREADY.
*/
res = -EINPROGRESS;
+ break;
+ }
+
+ switch (sock->state) {
case SS_CONNECTING:
if (previous == SS_CONNECTING)
res = -EALREADY;
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 11/16] tipc: create TIPC_PROBING/TIPC_ESTABLISHED as new sk_states
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
Until now, tipc maintains probing state for connected sockets in
tsk->probing_state variable.
In this commit, we express this information as socket states and
this remove the variable. The sk_state is set to TIPC_PROBING
instead of setting probing_state to TIPC_CONN_PROBING. Similarly
sk_state is set to TIPC_ESTABLISHED instead of TIPC_CONN_OK.
There is no functional change in this commit.
Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
include/uapi/linux/tipc.h | 2 ++
net/tipc/socket.c | 23 +++++++++++++++++------
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
index 8a107085f268..189bfed0363c 100644
--- a/include/uapi/linux/tipc.h
+++ b/include/uapi/linux/tipc.h
@@ -181,6 +181,8 @@ struct tipc_event {
*/
enum {
TIPC_LISTEN = 1,
+ TIPC_PROBING,
+ TIPC_ESTABLISHED,
};
/*
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 7c9c97363e81..04d388c063a6 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -47,8 +47,6 @@
#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */
#define CONN_PROBING_INTERVAL msecs_to_jiffies(3600000) /* [ms] => 1 h */
#define TIPC_FWD_MSG 1
-#define TIPC_CONN_OK 0
-#define TIPC_CONN_PROBING 1
#define TIPC_MAX_PORT 0xffffffff
#define TIPC_MIN_PORT 1
@@ -345,6 +343,7 @@ static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
static int tipc_set_sk_state(struct sock *sk, int state)
{
int oldstate = sk->sk_socket->state;
+ int oldsk_state = sk->sk_state;
int res = -EINVAL;
switch (state) {
@@ -352,6 +351,17 @@ static int tipc_set_sk_state(struct sock *sk, int state)
if (oldstate == SS_UNCONNECTED)
res = 0;
break;
+ case TIPC_PROBING:
+ if (oldsk_state == TIPC_ESTABLISHED)
+ res = 0;
+ break;
+ case TIPC_ESTABLISHED:
+ if (oldsk_state == TIPC_PROBING ||
+ oldsk_state == TIPC_ESTABLISHED ||
+ oldstate == SS_CONNECTING ||
+ oldstate == SS_UNCONNECTED)
+ res = 0;
+ break;
}
if (res)
@@ -855,7 +865,8 @@ static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb,
if (!tsk_peer_msg(tsk, hdr))
goto exit;
- tsk->probing_state = TIPC_CONN_OK;
+ if (tipc_set_sk_state(sk, TIPC_ESTABLISHED))
+ goto exit;
if (mtyp == CONN_PROBE) {
msg_set_type(hdr, CONN_PROBE_REPLY);
@@ -1195,8 +1206,8 @@ static void tipc_sk_finish_conn(struct tipc_sock *tsk, u32 peer_port,
msg_set_lookup_scope(msg, 0);
msg_set_hdr_sz(msg, SHORT_H_SIZE);
- tsk->probing_state = TIPC_CONN_OK;
sk_reset_timer(sk, &sk->sk_timer, jiffies + CONN_PROBING_INTERVAL);
+ tipc_set_sk_state(sk, TIPC_ESTABLISHED);
tipc_node_add_conn(net, peer_node, tsk->portid, peer_port);
tsk->max_pkt = tipc_node_get_mtu(net, peer_node, tsk->portid);
tsk->peer_caps = tipc_node_get_capabilities(net, peer_node);
@@ -2260,7 +2271,7 @@ static void tipc_sk_timeout(unsigned long data)
peer_port = tsk_peer_port(tsk);
peer_node = tsk_peer_node(tsk);
- if (tsk->probing_state == TIPC_CONN_PROBING) {
+ if (sk->sk_state == TIPC_PROBING) {
if (!sock_owned_by_user(sk)) {
sk->sk_socket->state = SS_DISCONNECTING;
tipc_node_remove_conn(sock_net(sk), tsk_peer_node(tsk),
@@ -2278,7 +2289,7 @@ static void tipc_sk_timeout(unsigned long data)
skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE,
INT_H_SIZE, 0, peer_node, own_node,
peer_port, tsk->portid, TIPC_OK);
- tsk->probing_state = TIPC_CONN_PROBING;
+ tipc_set_sk_state(sk, TIPC_PROBING);
sk_reset_timer(sk, &sk->sk_timer, jiffies + CONN_PROBING_INTERVAL);
bh_unlock_sock(sk);
if (skb)
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 10/16] tipc: create TIPC_LISTEN as a new sk_state
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
Until now, tipc maintains the socket state in sock->state variable.
This is used to maintain generic socket states, but in tipc
we overload it and save tipc socket states like TIPC_LISTEN.
Other protocols like TCP, UDP store protocol specific states
in sk->sk_state instead.
In this commit, we :
- declare a new tipc state TIPC_LISTEN, that replaces SS_LISTEN
- Create a new function tipc_set_state(), to update sk->sk_state.
- TIPC_LISTEN state is maintained in sk->sk_state.
- replace references to SS_LISTEN with TIPC_LISTEN.
There is no functional change in this commit.
Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
include/uapi/linux/tipc.h | 7 ++++++
net/tipc/socket.c | 59 ++++++++++++++++++++++++++++++++---------------
2 files changed, 47 insertions(+), 19 deletions(-)
diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
index bf049e8fe31b..8a107085f268 100644
--- a/include/uapi/linux/tipc.h
+++ b/include/uapi/linux/tipc.h
@@ -177,6 +177,13 @@ struct tipc_event {
};
/*
+ * Definitions for the TIPC protocol sk_state field.
+ */
+enum {
+ TIPC_LISTEN = 1,
+};
+
+/*
* Socket API
*/
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 6c71951b7d0c..7c9c97363e81 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -44,8 +44,6 @@
#include "bcast.h"
#include "netlink.h"
-#define SS_LISTENING -1 /* socket is listening */
-
#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */
#define CONN_PROBING_INTERVAL msecs_to_jiffies(3600000) /* [ms] => 1 h */
#define TIPC_FWD_MSG 1
@@ -337,6 +335,32 @@ static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
return false;
}
+/* tipc_set_sk_state - set the sk_state of the socket
+ * @sk: socket
+ *
+ * Caller must hold socket lock
+ *
+ * Returns 0 on success, errno otherwise
+ */
+static int tipc_set_sk_state(struct sock *sk, int state)
+{
+ int oldstate = sk->sk_socket->state;
+ int res = -EINVAL;
+
+ switch (state) {
+ case TIPC_LISTEN:
+ if (oldstate == SS_UNCONNECTED)
+ res = 0;
+ break;
+ }
+
+ if (res)
+ return res;
+
+ sk->sk_state = state;
+ return 0;
+}
+
/**
* tipc_sk_create - create a TIPC socket
* @net: network namespace (must be default network)
@@ -666,15 +690,22 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
switch ((int)sock->state) {
case SS_UNCONNECTED:
- if (!tsk->link_cong)
- mask |= POLLOUT;
+ switch (sk->sk_state) {
+ case TIPC_LISTEN:
+ if (!skb_queue_empty(&sk->sk_receive_queue))
+ mask |= (POLLIN | POLLRDNORM);
+ break;
+ default:
+ if (!tsk->link_cong)
+ mask |= POLLOUT;
+ break;
+ }
break;
case SS_CONNECTED:
if (!tsk->link_cong && !tsk_conn_cong(tsk))
mask |= POLLOUT;
/* fall thru' */
case SS_CONNECTING:
- case SS_LISTENING:
if (!skb_queue_empty(&sk->sk_receive_queue))
mask |= (POLLIN | POLLRDNORM);
break;
@@ -925,7 +956,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
return -EINVAL;
}
if (!is_connectionless) {
- if (sock->state == SS_LISTENING)
+ if (sk->sk_state == TIPC_LISTEN)
return -EPIPE;
if (sock->state != SS_UNCONNECTED)
return -EISCONN;
@@ -1651,7 +1682,6 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
msg_set_dest_droppable(hdr, 1);
return false;
- case SS_LISTENING:
case SS_UNCONNECTED:
/* Accept only SYN message */
@@ -2026,15 +2056,9 @@ static int tipc_listen(struct socket *sock, int len)
int res;
lock_sock(sk);
-
- if (sock->state != SS_UNCONNECTED)
- res = -EINVAL;
- else {
- sock->state = SS_LISTENING;
- res = 0;
- }
-
+ res = tipc_set_sk_state(sk, TIPC_LISTEN);
release_sock(sk);
+
return res;
}
@@ -2060,9 +2084,6 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo)
err = 0;
if (!skb_queue_empty(&sk->sk_receive_queue))
break;
- err = -EINVAL;
- if (sock->state != SS_LISTENING)
- break;
err = -EAGAIN;
if (!timeo)
break;
@@ -2093,7 +2114,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
lock_sock(sk);
- if (sock->state != SS_LISTENING) {
+ if (sk->sk_state != TIPC_LISTEN) {
res = -EINVAL;
goto exit;
}
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 09/16] tipc: remove socket state SS_READY
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
Until now, tipc socket state SS_READY declares that the socket is a
connectionless socket.
In this commit, we remove the state SS_READY and replace it with a
condition which returns true for datagram / connectionless sockets.
Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
net/tipc/socket.c | 49 +++++++++++++++++++++++++++++++------------------
1 file changed, 31 insertions(+), 18 deletions(-)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 82e06488de08..6c71951b7d0c 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -45,7 +45,6 @@
#include "netlink.h"
#define SS_LISTENING -1 /* socket is listening */
-#define SS_READY -2 /* socket is connectionless */
#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */
#define CONN_PROBING_INTERVAL msecs_to_jiffies(3600000) /* [ms] => 1 h */
@@ -294,6 +293,16 @@ static bool tipc_sk_connected(struct sock *sk)
return sk->sk_socket->state == SS_CONNECTED;
}
+/* tipc_sk_type_connectionless - check if the socket is datagram socket
+ * @sk: socket
+ *
+ * Returns true if connection less, false otherwise
+ */
+static bool tipc_sk_type_connectionless(struct sock *sk)
+{
+ return sk->sk_type == SOCK_RDM || sk->sk_type == SOCK_DGRAM;
+}
+
/* tsk_peer_msg - verify if message was sent by connected port's peer
*
* Handles cases where the node's network address has changed from
@@ -345,7 +354,6 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
{
struct tipc_net *tn;
const struct proto_ops *ops;
- socket_state state;
struct sock *sk;
struct tipc_sock *tsk;
struct tipc_msg *msg;
@@ -357,16 +365,13 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
switch (sock->type) {
case SOCK_STREAM:
ops = &stream_ops;
- state = SS_UNCONNECTED;
break;
case SOCK_SEQPACKET:
ops = &packet_ops;
- state = SS_UNCONNECTED;
break;
case SOCK_DGRAM:
case SOCK_RDM:
ops = &msg_ops;
- state = SS_READY;
break;
default:
return -EPROTOTYPE;
@@ -387,7 +392,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
/* Finish initializing socket data structures */
sock->ops = ops;
- sock->state = state;
+ sock->state = SS_UNCONNECTED;
sock_init_data(sock, sk);
if (tipc_sk_insert(tsk)) {
pr_warn("Socket create failed; port number exhausted\n");
@@ -407,7 +412,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
tsk->snd_win = tsk_adv_blocks(RCVBUF_MIN);
tsk->rcv_win = tsk->snd_win;
- if (sock->state == SS_READY) {
+ if (tipc_sk_type_connectionless(sk)) {
tsk_set_unreturnable(tsk, true);
if (sock->type == SOCK_DGRAM)
tsk_set_unreliable(tsk, true);
@@ -651,12 +656,19 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
sock_poll_wait(file, sk_sleep(sk), wait);
+ if (tipc_sk_type_connectionless(sk)) {
+ if (!tsk->link_cong)
+ mask |= POLLOUT;
+ if (!skb_queue_empty(&sk->sk_receive_queue))
+ mask |= (POLLIN | POLLRDNORM);
+ return mask;
+ }
+
switch ((int)sock->state) {
case SS_UNCONNECTED:
if (!tsk->link_cong)
mask |= POLLOUT;
break;
- case SS_READY:
case SS_CONNECTED:
if (!tsk->link_cong && !tsk_conn_cong(tsk))
mask |= POLLOUT;
@@ -893,6 +905,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
struct tipc_msg *mhdr = &tsk->phdr;
u32 dnode, dport;
struct sk_buff_head pktchain;
+ bool is_connectionless = tipc_sk_type_connectionless(sk);
struct sk_buff *skb;
struct tipc_name_seq *seq;
struct iov_iter save;
@@ -903,7 +916,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
if (dsz > TIPC_MAX_USER_MSG_SIZE)
return -EMSGSIZE;
if (unlikely(!dest)) {
- if (sock->state == SS_READY && tsk->peer.family == AF_TIPC)
+ if (is_connectionless && tsk->peer.family == AF_TIPC)
dest = &tsk->peer;
else
return -EDESTADDRREQ;
@@ -911,7 +924,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
dest->family != AF_TIPC) {
return -EINVAL;
}
- if (unlikely(sock->state != SS_READY)) {
+ if (!is_connectionless) {
if (sock->state == SS_LISTENING)
return -EPIPE;
if (sock->state != SS_UNCONNECTED)
@@ -966,7 +979,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
TIPC_SKB_CB(skb)->wakeup_pending = tsk->link_cong;
rc = tipc_node_xmit(net, &pktchain, dnode, tsk->portid);
if (likely(!rc)) {
- if (sock->state != SS_READY)
+ if (!is_connectionless)
sock->state = SS_CONNECTING;
return dsz;
}
@@ -1337,6 +1350,7 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len,
struct tipc_sock *tsk = tipc_sk(sk);
struct sk_buff *buf;
struct tipc_msg *msg;
+ bool is_connectionless = tipc_sk_type_connectionless(sk);
long timeo;
unsigned int sz;
u32 err;
@@ -1348,7 +1362,7 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len,
lock_sock(sk);
- if (unlikely(sock->state == SS_UNCONNECTED)) {
+ if (!is_connectionless && unlikely(sock->state == SS_UNCONNECTED)) {
res = -ENOTCONN;
goto exit;
}
@@ -1393,8 +1407,8 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len,
goto exit;
res = sz;
} else {
- if ((sock->state == SS_READY) ||
- ((err == TIPC_CONN_SHUTDOWN) || m->msg_control))
+ if (is_connectionless || err == TIPC_CONN_SHUTDOWN ||
+ m->msg_control)
res = 0;
else
res = -ECONNRESET;
@@ -1403,7 +1417,7 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len,
if (unlikely(flags & MSG_PEEK))
goto exit;
- if (likely(sock->state != SS_READY)) {
+ if (likely(!is_connectionless)) {
tsk->rcv_unacked += tsk_inc(tsk, hlen + sz);
if (unlikely(tsk->rcv_unacked >= (tsk->rcv_win / 4)))
tipc_sk_send_ack(tsk);
@@ -1699,7 +1713,6 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *skb)
static bool filter_rcv(struct sock *sk, struct sk_buff *skb,
struct sk_buff_head *xmitq)
{
- struct socket *sock = sk->sk_socket;
struct tipc_sock *tsk = tipc_sk(sk);
struct tipc_msg *hdr = buf_msg(skb);
unsigned int limit = rcvbuf_limit(sk, skb);
@@ -1725,7 +1738,7 @@ static bool filter_rcv(struct sock *sk, struct sk_buff *skb,
}
/* Reject if wrong message type for current socket state */
- if (unlikely(sock->state == SS_READY)) {
+ if (tipc_sk_type_connectionless(sk)) {
if (msg_connected(hdr)) {
err = TIPC_ERR_NO_PORT;
goto reject;
@@ -1935,7 +1948,7 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
lock_sock(sk);
/* DGRAM/RDM connect(), just save the destaddr */
- if (sock->state == SS_READY) {
+ if (tipc_sk_type_connectionless(sk)) {
if (dst->family == AF_UNSPEC) {
memset(&tsk->peer, 0, sizeof(struct sockaddr_tipc));
} else if (destlen != sizeof(struct sockaddr_tipc)) {
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 08/16] tipc: remove probing_intv from tipc_sock
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
Until now, probing_intv is a variable in struct tipc_sock but is
always set to a constant CONN_PROBING_INTERVAL. The socket
connection is probed based on this value.
In this commit, we remove this variable and setup the socket
timer based on the constant CONN_PROBING_INTERVAL.
There is no functional change in this commit.
Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
net/tipc/socket.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 8299964cd373..82e06488de08 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -67,7 +67,6 @@
* @publications: list of publications for port
* @pub_count: total # of publications port has made during its lifetime
* @probing_state:
- * @probing_intv:
* @conn_timeout: the time we can wait for an unresponded setup request
* @dupl_rcvcnt: number of bytes counted twice, in both backlog and rcv queue
* @link_cong: non-zero if owner must sleep because of link congestion
@@ -89,7 +88,6 @@ struct tipc_sock {
struct list_head publications;
u32 pub_count;
u32 probing_state;
- unsigned long probing_intv;
uint conn_timeout;
atomic_t dupl_rcvcnt;
bool link_cong;
@@ -1153,9 +1151,8 @@ static void tipc_sk_finish_conn(struct tipc_sock *tsk, u32 peer_port,
msg_set_lookup_scope(msg, 0);
msg_set_hdr_sz(msg, SHORT_H_SIZE);
- tsk->probing_intv = CONN_PROBING_INTERVAL;
tsk->probing_state = TIPC_CONN_OK;
- sk_reset_timer(sk, &sk->sk_timer, jiffies + tsk->probing_intv);
+ sk_reset_timer(sk, &sk->sk_timer, jiffies + CONN_PROBING_INTERVAL);
tipc_node_add_conn(net, peer_node, tsk->portid, peer_port);
tsk->max_pkt = tipc_node_get_mtu(net, peer_node, tsk->portid);
tsk->peer_caps = tipc_node_get_capabilities(net, peer_node);
@@ -2240,13 +2237,15 @@ static void tipc_sk_timeout(unsigned long data)
sk_reset_timer(sk, &sk->sk_timer, (HZ / 20));
}
- } else {
- skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE,
- INT_H_SIZE, 0, peer_node, own_node,
- peer_port, tsk->portid, TIPC_OK);
- tsk->probing_state = TIPC_CONN_PROBING;
- sk_reset_timer(sk, &sk->sk_timer, jiffies + tsk->probing_intv);
+ bh_unlock_sock(sk);
+ goto exit;
}
+
+ skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE,
+ INT_H_SIZE, 0, peer_node, own_node,
+ peer_port, tsk->portid, TIPC_OK);
+ tsk->probing_state = TIPC_CONN_PROBING;
+ sk_reset_timer(sk, &sk->sk_timer, jiffies + CONN_PROBING_INTERVAL);
bh_unlock_sock(sk);
if (skb)
tipc_node_xmit_skb(sock_net(sk), skb, peer_node, tsk->portid);
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 07/16] tipc: remove tsk->connected from tipc_sock
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
Until now, we determine if a socket is connected or not based on
tsk->connected, which is set once when the probing state is set
to TIPC_CONN_OK. It is unset when the sock->state is updated from
SS_CONNECTED to any other state.
In this commit, we remove connected variable from tipc_sock and
derive socket connection status from the following condition:
sock->state == SS_CONNECTED => tsk->connected
There is no functional change in this commit.
Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
net/tipc/socket.c | 36 +++++++++++++++++++-----------------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index ebe000888667..8299964cd373 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -58,7 +58,6 @@
/**
* struct tipc_sock - TIPC socket structure
* @sk: socket - interacts with 'port' and with user via the socket API
- * @connected: non-zero if port is currently connected to a peer port
* @conn_type: TIPC type used when connection was established
* @conn_instance: TIPC instance used when connection was established
* @published: non-zero if port has one or more associated names
@@ -80,7 +79,6 @@
*/
struct tipc_sock {
struct sock sk;
- int connected;
u32 conn_type;
u32 conn_instance;
int published;
@@ -293,6 +291,11 @@ static void tsk_rej_rx_queue(struct sock *sk)
tipc_sk_respond(sk, skb, TIPC_ERR_NO_PORT);
}
+static bool tipc_sk_connected(struct sock *sk)
+{
+ return sk->sk_socket->state == SS_CONNECTED;
+}
+
/* tsk_peer_msg - verify if message was sent by connected port's peer
*
* Handles cases where the node's network address has changed from
@@ -300,12 +303,13 @@ static void tsk_rej_rx_queue(struct sock *sk)
*/
static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
{
- struct tipc_net *tn = net_generic(sock_net(&tsk->sk), tipc_net_id);
+ struct sock *sk = &tsk->sk;
+ struct tipc_net *tn = net_generic(sock_net(sk), tipc_net_id);
u32 peer_port = tsk_peer_port(tsk);
u32 orig_node;
u32 peer_node;
- if (unlikely(!tsk->connected))
+ if (unlikely(!tipc_sk_connected(sk)))
return false;
if (unlikely(msg_origport(msg) != peer_port))
@@ -470,7 +474,6 @@ static int tipc_release(struct socket *sock)
if ((sock->state == SS_CONNECTING) ||
(sock->state == SS_CONNECTED)) {
sock->state = SS_DISCONNECTING;
- tsk->connected = 0;
tipc_node_remove_conn(net, dnode, tsk->portid);
}
tipc_sk_respond(sk, skb, TIPC_ERR_NO_PORT);
@@ -480,7 +483,7 @@ static int tipc_release(struct socket *sock)
tipc_sk_withdraw(tsk, 0, NULL);
sk_stop_timer(sk, &sk->sk_timer);
tipc_sk_remove(tsk);
- if (tsk->connected) {
+ if (tipc_sk_connected(sk)) {
skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode,
tsk_own_node(tsk), tsk_peer_port(tsk),
@@ -1010,7 +1013,7 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p)
done = sk_wait_event(sk, timeo_p,
(!tsk->link_cong &&
!tsk_conn_cong(tsk)) ||
- !tsk->connected);
+ !tipc_sk_connected(sk));
finish_wait(sk_sleep(sk), &wait);
} while (!done);
return 0;
@@ -1152,7 +1155,6 @@ static void tipc_sk_finish_conn(struct tipc_sock *tsk, u32 peer_port,
tsk->probing_intv = CONN_PROBING_INTERVAL;
tsk->probing_state = TIPC_CONN_OK;
- tsk->connected = 1;
sk_reset_timer(sk, &sk->sk_timer, jiffies + tsk->probing_intv);
tipc_node_add_conn(net, peer_node, tsk->portid, peer_port);
tsk->max_pkt = tipc_node_get_mtu(net, peer_node, tsk->portid);
@@ -1261,13 +1263,14 @@ static int tipc_sk_anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
static void tipc_sk_send_ack(struct tipc_sock *tsk)
{
- struct net *net = sock_net(&tsk->sk);
+ struct sock *sk = &tsk->sk;
+ struct net *net = sock_net(sk);
struct sk_buff *skb = NULL;
struct tipc_msg *msg;
u32 peer_port = tsk_peer_port(tsk);
u32 dnode = tsk_peer_node(tsk);
- if (!tsk->connected)
+ if (!tipc_sk_connected(sk))
return;
skb = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0,
dnode, tsk_own_node(tsk), peer_port,
@@ -1596,7 +1599,6 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
if (unlikely(msg_errcode(hdr))) {
sock->state = SS_DISCONNECTING;
- tsk->connected = 0;
/* Let timer expire on it's own */
tipc_node_remove_conn(net, tsk_peer_node(tsk),
tsk->portid);
@@ -2189,7 +2191,6 @@ static int tipc_shutdown(struct socket *sock, int how)
if (skb)
tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
}
- tsk->connected = 0;
sock->state = SS_DISCONNECTING;
tipc_node_remove_conn(net, dnode, tsk->portid);
/* fall through */
@@ -2221,7 +2222,7 @@ static void tipc_sk_timeout(unsigned long data)
u32 own_node = tsk_own_node(tsk);
bh_lock_sock(sk);
- if (!tsk->connected) {
+ if (!tipc_sk_connected(sk)) {
bh_unlock_sock(sk);
goto exit;
}
@@ -2231,7 +2232,6 @@ static void tipc_sk_timeout(unsigned long data)
if (tsk->probing_state == TIPC_CONN_PROBING) {
if (!sock_owned_by_user(sk)) {
sk->sk_socket->state = SS_DISCONNECTING;
- tsk->connected = 0;
tipc_node_remove_conn(sock_net(sk), tsk_peer_node(tsk),
tsk_peer_port(tsk));
sk->sk_state_change(sk);
@@ -2257,11 +2257,12 @@ static void tipc_sk_timeout(unsigned long data)
static int tipc_sk_publish(struct tipc_sock *tsk, uint scope,
struct tipc_name_seq const *seq)
{
- struct net *net = sock_net(&tsk->sk);
+ struct sock *sk = &tsk->sk;
+ struct net *net = sock_net(sk);
struct publication *publ;
u32 key;
- if (tsk->connected)
+ if (tipc_sk_connected(sk))
return -EINVAL;
key = tsk->portid + tsk->pub_count + 1;
if (key == tsk->portid)
@@ -2719,6 +2720,7 @@ static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb,
struct nlattr *attrs;
struct net *net = sock_net(skb->sk);
struct tipc_net *tn = net_generic(net, tipc_net_id);
+ struct sock *sk = &tsk->sk;
hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
&tipc_genl_family, NLM_F_MULTI, TIPC_NL_SOCK_GET);
@@ -2733,7 +2735,7 @@ static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb,
if (nla_put_u32(skb, TIPC_NLA_SOCK_ADDR, tn->own_addr))
goto attr_msg_cancel;
- if (tsk->connected) {
+ if (tipc_sk_connected(sk)) {
err = __tipc_nl_add_sk_con(skb, tsk);
if (err)
goto attr_msg_cancel;
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 06/16] tipc: remove tsk->connected for connectionless sockets
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
Until now, for connectionless sockets the peer information during
connect is stored in tsk->peer and a connection state is set in
tsk->connected. This is redundant.
In this commit, for connectionless sockets we update:
- __tipc_sendmsg(), when the destination is NULL the peer existence
is determined by tsk->peer.family, instead of tsk->connected.
- tipc_connect(), remove set/unset of tsk->connected.
Hence tsk->connected is no longer used for connectionless sockets.
There is no functional change in this commit.
Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
net/tipc/socket.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 8bc9c32c41b5..ebe000888667 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -902,7 +902,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
if (dsz > TIPC_MAX_USER_MSG_SIZE)
return -EMSGSIZE;
if (unlikely(!dest)) {
- if (tsk->connected && sock->state == SS_READY)
+ if (sock->state == SS_READY && tsk->peer.family == AF_TIPC)
dest = &tsk->peer;
else
return -EDESTADDRREQ;
@@ -1939,12 +1939,10 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
if (sock->state == SS_READY) {
if (dst->family == AF_UNSPEC) {
memset(&tsk->peer, 0, sizeof(struct sockaddr_tipc));
- tsk->connected = 0;
} else if (destlen != sizeof(struct sockaddr_tipc)) {
res = -EINVAL;
} else {
memcpy(&tsk->peer, dest, destlen);
- tsk->connected = 1;
}
goto exit;
}
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 05/16] tipc: rename tsk->remote to tsk->peer for consistent naming
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
Until now, the peer information for connect is stored in tsk->remote
but the rest of code uses the name peer for peer/remote.
In this commit, we rename tsk->remote to tsk->peer to align with
naming convention followed in the rest of the code.
There is no functional change in this commit.
Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
net/tipc/socket.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 6e3774a7c831..8bc9c32c41b5 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -65,7 +65,6 @@
* @max_pkt: maximum packet size "hint" used when building messages sent by port
* @portid: unique port identity in TIPC socket hash table
* @phdr: preformatted message header used when sending messages
- * @port_list: adjacent ports in TIPC's global list of ports
* @publications: list of publications for port
* @pub_count: total # of publications port has made during its lifetime
* @probing_state:
@@ -75,7 +74,7 @@
* @link_cong: non-zero if owner must sleep because of link congestion
* @sent_unacked: # messages sent by socket, and not yet acked by peer
* @rcv_unacked: # messages read by user, but not yet acked back to peer
- * @remote: 'connected' peer for dgram/rdm
+ * @peer: 'connected' peer for dgram/rdm
* @node: hash table node
* @rcu: rcu struct for tipc_sock
*/
@@ -101,7 +100,7 @@ struct tipc_sock {
u16 peer_caps;
u16 rcv_unacked;
u16 rcv_win;
- struct sockaddr_tipc remote;
+ struct sockaddr_tipc peer;
struct rhash_head node;
struct rcu_head rcu;
};
@@ -904,7 +903,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
return -EMSGSIZE;
if (unlikely(!dest)) {
if (tsk->connected && sock->state == SS_READY)
- dest = &tsk->remote;
+ dest = &tsk->peer;
else
return -EDESTADDRREQ;
} else if (unlikely(m->msg_namelen < sizeof(*dest)) ||
@@ -1939,12 +1938,12 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
/* DGRAM/RDM connect(), just save the destaddr */
if (sock->state == SS_READY) {
if (dst->family == AF_UNSPEC) {
- memset(&tsk->remote, 0, sizeof(struct sockaddr_tipc));
+ memset(&tsk->peer, 0, sizeof(struct sockaddr_tipc));
tsk->connected = 0;
} else if (destlen != sizeof(struct sockaddr_tipc)) {
res = -EINVAL;
} else {
- memcpy(&tsk->remote, dest, destlen);
+ memcpy(&tsk->peer, dest, destlen);
tsk->connected = 1;
}
goto exit;
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 04/16] tipc: rename struct tipc_skb_cb member handle to bytes_read
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
In this commit, we rename handle to bytes_read indicating the
purpose of the member.
Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
net/tipc/msg.h | 2 +-
net/tipc/socket.c | 18 ++++++++++--------
2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index c3832cdf2278..a2aa01b442ef 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -95,7 +95,7 @@ struct plist;
#define TIPC_MEDIA_INFO_OFFSET 5
struct tipc_skb_cb {
- void *handle;
+ u32 bytes_read;
struct sk_buff *tail;
bool validated;
bool wakeup_pending;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 82aec2eb8497..6e3774a7c831 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -465,7 +465,7 @@ static int tipc_release(struct socket *sock)
skb = __skb_dequeue(&sk->sk_receive_queue);
if (skb == NULL)
break;
- if (TIPC_SKB_CB(skb)->handle != NULL)
+ if (TIPC_SKB_CB(skb)->bytes_read)
kfree_skb(skb);
else {
if ((sock->state == SS_CONNECTING) ||
@@ -1435,7 +1435,7 @@ static int tipc_recv_stream(struct socket *sock, struct msghdr *m,
struct tipc_msg *msg;
long timeo;
unsigned int sz;
- int sz_to_copy, target, needed;
+ int target;
int sz_copied = 0;
u32 err;
int res = 0, hlen;
@@ -1483,11 +1483,13 @@ static int tipc_recv_stream(struct socket *sock, struct msghdr *m,
/* Capture message data (if valid) & compute return value (always) */
if (!err) {
- u32 offset = (u32)(unsigned long)(TIPC_SKB_CB(buf)->handle);
+ u32 offset = (u32)(TIPC_SKB_CB(buf)->bytes_read);
+ u32 needed;
+ int sz_to_copy;
sz -= offset;
needed = (buf_len - sz_copied);
- sz_to_copy = (sz <= needed) ? sz : needed;
+ sz_to_copy = min(sz, needed);
res = skb_copy_datagram_msg(buf, hlen + offset, m, sz_to_copy);
if (res)
@@ -1497,8 +1499,8 @@ static int tipc_recv_stream(struct socket *sock, struct msghdr *m,
if (sz_to_copy < sz) {
if (!(flags & MSG_PEEK))
- TIPC_SKB_CB(buf)->handle =
- (void *)(unsigned long)(offset + sz_to_copy);
+ TIPC_SKB_CB(buf)->bytes_read =
+ offset + sz_to_copy;
goto exit;
}
} else {
@@ -1742,7 +1744,7 @@ static bool filter_rcv(struct sock *sk, struct sk_buff *skb,
}
/* Enqueue message */
- TIPC_SKB_CB(skb)->handle = NULL;
+ TIPC_SKB_CB(skb)->bytes_read = 0;
__skb_queue_tail(&sk->sk_receive_queue, skb);
skb_set_owner_r(skb, sk);
@@ -2177,7 +2179,7 @@ static int tipc_shutdown(struct socket *sock, int how)
/* Disconnect and send a 'FIN+' or 'FIN-' message to peer */
skb = __skb_dequeue(&sk->sk_receive_queue);
if (skb) {
- if (TIPC_SKB_CB(skb)->handle != NULL) {
+ if (TIPC_SKB_CB(skb)->bytes_read) {
kfree_skb(skb);
goto restart;
}
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 03/16] tipc: set kern=0 in sk_alloc() during tipc_accept()
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
Until now, tipc_accept() calls sk_alloc() with kern=1. This is
incorrect as the data socket's owner is the user application.
Thus for these accepted data sockets the network namespace
refcount is skipped.
In this commit, we fix this by setting kern=0.
Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
net/tipc/socket.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index cd01deb1da9c..82aec2eb8497 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2093,7 +2093,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
buf = skb_peek(&sk->sk_receive_queue);
- res = tipc_sk_create(sock_net(sock->sk), new_sock, 0, 1);
+ res = tipc_sk_create(sock_net(sock->sk), new_sock, 0, 0);
if (res)
goto exit;
security_sk_clone(sock->sk, new_sock->sk);
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 02/16] tipc: wakeup sleeping users at disconnect
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
Until now, in filter_connect() when we terminate a connection due to
an error message from peer, we set the socket state to DISCONNECTING.
The socket is notified about this broken connection using EPIPE when
a user tries to send a message. However if a socket was waiting on a
poll() while the connection is being terminated, we fail to wakeup
that socket.
In this commit, we wakeup sleeping sockets at connection termination.
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
net/tipc/socket.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index adf3e6ecf61e..cd01deb1da9c 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1599,6 +1599,7 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
/* Let timer expire on it's own */
tipc_node_remove_conn(net, tsk_peer_node(tsk),
tsk->portid);
+ sk->sk_state_change(sk);
}
return true;
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 01/16] tipc: return early for non-blocking sockets at link congestion
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
Until now, in stream/mcast send() we pass the message to the link
layer even when the link is congested and add the socket to the
link's wakeup queue. This is unnecessary for non-blocking sockets.
If a socket is set to non-blocking and sends multicast with zero
back off time while receiving EAGAIN, we exhaust the memory.
In this commit, we return immediately at stream/mcast send() for
non-blocking sockets.
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
net/tipc/socket.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index f9f5f3c3dab5..adf3e6ecf61e 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -697,6 +697,9 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
uint mtu;
int rc;
+ if (!timeo && tsk->link_cong)
+ return -ELINKCONG;
+
msg_set_type(mhdr, TIPC_MCAST_MSG);
msg_set_lookup_scope(mhdr, TIPC_CLUSTER_SCOPE);
msg_set_destport(mhdr, 0);
@@ -1072,6 +1075,9 @@ static int __tipc_send_stream(struct socket *sock, struct msghdr *m, size_t dsz)
}
timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
+ if (!timeo && tsk->link_cong)
+ return -ELINKCONG;
+
dnode = tsk_peer_node(tsk);
skb_queue_head_init(&pktchain);
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox