lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAPv3WKcO5TLMrsTLMumG1fc=cPA4JLSh4JMBgSjT45oiCgxLLw@mail.gmail.com>
Date:   Thu, 4 Feb 2021 20:00:07 +0100
From:   Marcin Wojtas <mw@...ihalf.com>
To:     Stefan Chulski <stefanc@...vell.com>
Cc:     netdev <netdev@...r.kernel.org>,
        Thomas Petazzoni <thomas.petazzoni@...tlin.com>,
        "David S. Miller" <davem@...emloft.net>, nadavh@...vell.com,
        Yan Markman <ymarkman@...vell.com>,
        Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
        Jakub Kicinski <kuba@...nel.org>,
        Russell King - ARM Linux <linux@...linux.org.uk>,
        Andrew Lunn <andrew@...n.ch>,
        Russell King <rmk+kernel@...linux.org.uk>, atenart@...nel.org
Subject: Re: [PATCH v7 net-next 10/15] net: mvpp2: add RXQ flow control configurations

Hi,

wt., 2 lut 2021 o 09:18 <stefanc@...vell.com> napisaƂ(a):
>
> From: Stefan Chulski <stefanc@...vell.com>
>
> This patch adds RXQ flow control configurations.
> Flow control disabled by default.
> Minimum ring size limited to 1024 descriptors.
>
> Signed-off-by: Stefan Chulski <stefanc@...vell.com>
> ---
>  drivers/net/ethernet/marvell/mvpp2/mvpp2.h      |  35 +++++-
>  drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 116 ++++++++++++++++++++
>  2 files changed, 150 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
> index e010410..0f27be0 100644
> --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
> +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
> @@ -766,9 +766,36 @@
>  #define MSS_SRAM_SIZE                  0x800
>  #define MSS_FC_COM_REG                 0
>  #define FLOW_CONTROL_ENABLE_BIT                BIT(0)
> +#define FLOW_CONTROL_UPDATE_COMMAND_BIT        BIT(31)
>  #define FC_QUANTA                      0xFFFF
>  #define FC_CLK_DIVIDER                 100
> -#define MSS_THRESHOLD_STOP             768
> +
> +#define MSS_RXQ_TRESH_BASE             0x200
> +#define MSS_RXQ_TRESH_OFFS             4
> +#define MSS_RXQ_TRESH_REG(q, fq)       (MSS_RXQ_TRESH_BASE + (((q) + (fq)) \
> +                                       * MSS_RXQ_TRESH_OFFS))
> +
> +#define MSS_RXQ_TRESH_START_MASK       0xFFFF
> +#define MSS_RXQ_TRESH_STOP_MASK                (0xFFFF << MSS_RXQ_TRESH_STOP_OFFS)
> +#define MSS_RXQ_TRESH_STOP_OFFS                16
> +
> +#define MSS_RXQ_ASS_BASE       0x80
> +#define MSS_RXQ_ASS_OFFS       4
> +#define MSS_RXQ_ASS_PER_REG    4
> +#define MSS_RXQ_ASS_PER_OFFS   8
> +#define MSS_RXQ_ASS_PORTID_OFFS        0
> +#define MSS_RXQ_ASS_PORTID_MASK        0x3
> +#define MSS_RXQ_ASS_HOSTID_OFFS        2
> +#define MSS_RXQ_ASS_HOSTID_MASK        0x3F
> +
> +#define MSS_RXQ_ASS_Q_BASE(q, fq) ((((q) + (fq)) % MSS_RXQ_ASS_PER_REG)         \
> +                                 * MSS_RXQ_ASS_PER_OFFS)
> +#define MSS_RXQ_ASS_PQ_BASE(q, fq) ((((q) + (fq)) / MSS_RXQ_ASS_PER_REG) \
> +                                  * MSS_RXQ_ASS_OFFS)
> +#define MSS_RXQ_ASS_REG(q, fq) (MSS_RXQ_ASS_BASE + MSS_RXQ_ASS_PQ_BASE(q, fq))
> +
> +#define MSS_THRESHOLD_STOP     768
> +#define MSS_THRESHOLD_START    1024
>
>  /* RX buffer constants */
>  #define MVPP2_SKB_SHINFO_SIZE \
> @@ -1026,6 +1053,9 @@ struct mvpp2 {
>
>         /* Global TX Flow Control config */
>         bool global_tx_fc;
> +
> +       /* Spinlocks for CM3 shared memory configuration */
> +       spinlock_t mss_spinlock;
>  };
>
>  struct mvpp2_pcpu_stats {
> @@ -1188,6 +1218,9 @@ struct mvpp2_port {
>         bool rx_hwtstamp;
>         enum hwtstamp_tx_types tx_hwtstamp_type;
>         struct mvpp2_hwtstamp_queue tx_hwtstamp_queue[2];
> +
> +       /* Firmware TX flow control */
> +       bool tx_fc;
>  };
>
>  /* The mvpp2_tx_desc and mvpp2_rx_desc structures describe the
> diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
> index 770f45a..d778ae1 100644
> --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
> +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
> @@ -742,6 +742,110 @@ static void *mvpp2_buf_alloc(struct mvpp2_port *port,
>         return data;
>  }
>
> +/* Routine enable flow control for RXQs condition */
> +static void mvpp2_rxq_enable_fc(struct mvpp2_port *port)
> +{
> +       int val, cm3_state, host_id, q;
> +       int fq = port->first_rxq;
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(&port->priv->mss_spinlock, flags);
> +
> +       /* Remove Flow control enable bit to prevent race between FW and Kernel
> +        * If Flow control were enabled, it would be re-enabled.

Nit:

s/were/was/

Thanks,
Marcin


> +        */
> +       val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
> +       cm3_state = (val & FLOW_CONTROL_ENABLE_BIT);
> +       val &= ~FLOW_CONTROL_ENABLE_BIT;
> +       mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);
> +
> +       /* Set same Flow control for all RXQs */
> +       for (q = 0; q < port->nrxqs; q++) {
> +               /* Set stop and start Flow control RXQ thresholds */
> +               val = MSS_THRESHOLD_START;
> +               val |= (MSS_THRESHOLD_STOP << MSS_RXQ_TRESH_STOP_OFFS);
> +               mvpp2_cm3_write(port->priv, MSS_RXQ_TRESH_REG(q, fq), val);
> +
> +               val = mvpp2_cm3_read(port->priv, MSS_RXQ_ASS_REG(q, fq));
> +               /* Set RXQ port ID */
> +               val &= ~(MSS_RXQ_ASS_PORTID_MASK << MSS_RXQ_ASS_Q_BASE(q, fq));
> +               val |= (port->id << MSS_RXQ_ASS_Q_BASE(q, fq));
> +               val &= ~(MSS_RXQ_ASS_HOSTID_MASK << (MSS_RXQ_ASS_Q_BASE(q, fq)
> +                       + MSS_RXQ_ASS_HOSTID_OFFS));
> +
> +               /* Calculate RXQ host ID:
> +                * In Single queue mode: Host ID equal to Host ID used for
> +                *                       shared RX interrupt
> +                * In Multi queue mode: Host ID equal to number of
> +                *                      RXQ ID / number of CoS queues
> +                * In Single resource mode: Host ID always equal to 0
> +                */
> +               if (queue_mode == MVPP2_QDIST_SINGLE_MODE)
> +                       host_id = port->nqvecs;
> +               else if (queue_mode == MVPP2_QDIST_MULTI_MODE)
> +                       host_id = q;
> +               else
> +                       host_id = 0;
> +
> +               /* Set RXQ host ID */
> +               val |= (host_id << (MSS_RXQ_ASS_Q_BASE(q, fq)
> +                       + MSS_RXQ_ASS_HOSTID_OFFS));
> +
> +               mvpp2_cm3_write(port->priv, MSS_RXQ_ASS_REG(q, fq), val);
> +       }
> +
> +       /* Notify Firmware that Flow control config space ready for update */
> +       val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
> +       val |= FLOW_CONTROL_UPDATE_COMMAND_BIT;
> +       val |= cm3_state;
> +       mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);
> +
> +       spin_unlock_irqrestore(&port->priv->mss_spinlock, flags);
> +}
> +
> +/* Routine disable flow control for RXQs condition */
> +static void mvpp2_rxq_disable_fc(struct mvpp2_port *port)
> +{
> +       int val, cm3_state, q;
> +       unsigned long flags;
> +       int fq = port->first_rxq;
> +
> +       spin_lock_irqsave(&port->priv->mss_spinlock, flags);
> +
> +       /* Remove Flow control enable bit to prevent race between FW and Kernel
> +        * If Flow control were enabled, it would be re-enabled.
> +        */
> +       val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
> +       cm3_state = (val & FLOW_CONTROL_ENABLE_BIT);
> +       val &= ~FLOW_CONTROL_ENABLE_BIT;
> +       mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);
> +
> +       /* Disable Flow control for all RXQs */
> +       for (q = 0; q < port->nrxqs; q++) {
> +               /* Set threshold 0 to disable Flow control */
> +               val = 0;
> +               val |= (0 << MSS_RXQ_TRESH_STOP_OFFS);
> +               mvpp2_cm3_write(port->priv, MSS_RXQ_TRESH_REG(q, fq), val);
> +
> +               val = mvpp2_cm3_read(port->priv, MSS_RXQ_ASS_REG(q, fq));
> +
> +               val &= ~(MSS_RXQ_ASS_PORTID_MASK << MSS_RXQ_ASS_Q_BASE(q, fq));
> +
> +               val &= ~(MSS_RXQ_ASS_HOSTID_MASK << (MSS_RXQ_ASS_Q_BASE(q, fq)
> +                       + MSS_RXQ_ASS_HOSTID_OFFS));
> +
> +               mvpp2_cm3_write(port->priv, MSS_RXQ_ASS_REG(q, fq), val);
> +       }
> +
> +       /* Notify Firmware that Flow control config space ready for update */
> +       val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
> +       val |= FLOW_CONTROL_UPDATE_COMMAND_BIT;
> +       val |= cm3_state;
> +       mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);
> +
> +       spin_unlock_irqrestore(&port->priv->mss_spinlock, flags);
> +}
> +
>  /* Release buffer to BM */
>  static inline void mvpp2_bm_pool_put(struct mvpp2_port *port, int pool,
>                                      dma_addr_t buf_dma_addr,
> @@ -3006,6 +3110,9 @@ static void mvpp2_cleanup_rxqs(struct mvpp2_port *port)
>
>         for (queue = 0; queue < port->nrxqs; queue++)
>                 mvpp2_rxq_deinit(port, port->rxqs[queue]);
> +
> +       if (port->tx_fc)
> +               mvpp2_rxq_disable_fc(port);
>  }
>
>  /* Init all Rx queues for port */
> @@ -3018,6 +3125,10 @@ static int mvpp2_setup_rxqs(struct mvpp2_port *port)
>                 if (err)
>                         goto err_cleanup;
>         }
> +
> +       if (port->tx_fc)
> +               mvpp2_rxq_enable_fc(port);
> +
>         return 0;
>
>  err_cleanup:
> @@ -4317,6 +4428,8 @@ static int mvpp2_check_ringparam_valid(struct net_device *dev,
>
>         if (ring->rx_pending > MVPP2_MAX_RXD_MAX)
>                 new_rx_pending = MVPP2_MAX_RXD_MAX;
> +       else if (ring->rx_pending < MSS_THRESHOLD_START)
> +               new_rx_pending = MSS_THRESHOLD_START;
>         else if (!IS_ALIGNED(ring->rx_pending, 16))
>                 new_rx_pending = ALIGN(ring->rx_pending, 16);
>
> @@ -7170,6 +7283,9 @@ static int mvpp2_probe(struct platform_device *pdev)
>                         priv->hw_version = MVPP23;
>         }
>
> +       /* Init mss lock */
> +       spin_lock_init(&priv->mss_spinlock);
> +
>         /* Initialize network controller */
>         err = mvpp2_init(pdev, priv);
>         if (err < 0) {
> --
> 1.9.1
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ