Merge tag 'mlx5-updates-2020-09-21' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_main.c
index 472252e..961cdce 100644 (file)
@@ -158,16 +158,6 @@ static void mlx5e_update_carrier_work(struct work_struct *work)
        mutex_unlock(&priv->state_lock);
 }
 
-void mlx5e_update_ndo_stats(struct mlx5e_priv *priv)
-{
-       int i;
-
-       for (i = mlx5e_nic_stats_grps_num(priv) - 1; i >= 0; i--)
-               if (mlx5e_nic_stats_grps[i]->update_stats_mask &
-                   MLX5E_NDO_UPDATE_STATS)
-                       mlx5e_nic_stats_grps[i]->update_stats(priv);
-}
-
 static void mlx5e_update_stats_work(struct work_struct *work)
 {
        struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
@@ -399,7 +389,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
 
        if (params->xdp_prog)
                bpf_prog_inc(params->xdp_prog);
-       rq->xdp_prog = params->xdp_prog;
+       RCU_INIT_POINTER(rq->xdp_prog, params->xdp_prog);
 
        rq_xdp_ix = rq->ix;
        if (xsk)
@@ -408,7 +398,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
        if (err < 0)
                goto err_rq_wq_destroy;
 
-       rq->buff.map_dir = rq->xdp_prog ? DMA_BIDIRECTIONAL : DMA_FROM_DEVICE;
+       rq->buff.map_dir = params->xdp_prog ? DMA_BIDIRECTIONAL : DMA_FROM_DEVICE;
        rq->buff.headroom = mlx5e_get_rq_headroom(mdev, params, xsk);
        pool_size = 1 << params->log_rq_mtu_frames;
 
@@ -564,8 +554,8 @@ err_free:
        }
 
 err_rq_wq_destroy:
-       if (rq->xdp_prog)
-               bpf_prog_put(rq->xdp_prog);
+       if (params->xdp_prog)
+               bpf_prog_put(params->xdp_prog);
        xdp_rxq_info_unreg(&rq->xdp_rxq);
        page_pool_destroy(rq->page_pool);
        mlx5_wq_destroy(&rq->wq_ctrl);
@@ -575,10 +565,16 @@ err_rq_wq_destroy:
 
 static void mlx5e_free_rq(struct mlx5e_rq *rq)
 {
+       struct mlx5e_channel *c = rq->channel;
+       struct bpf_prog *old_prog = NULL;
        int i;
 
-       if (rq->xdp_prog)
-               bpf_prog_put(rq->xdp_prog);
+       /* drop_rq has neither channel nor xdp_prog. */
+       if (c)
+               old_prog = rcu_dereference_protected(rq->xdp_prog,
+                                                    lockdep_is_held(&c->priv->state_lock));
+       if (old_prog)
+               bpf_prog_put(old_prog);
 
        switch (rq->wq_type) {
        case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
@@ -874,7 +870,7 @@ void mlx5e_activate_rq(struct mlx5e_rq *rq)
 void mlx5e_deactivate_rq(struct mlx5e_rq *rq)
 {
        clear_bit(MLX5E_RQ_STATE_ENABLED, &rq->state);
-       napi_synchronize(&rq->channel->napi); /* prevent mlx5e_post_rx_wqes */
+       synchronize_rcu(); /* Sync with NAPI to prevent mlx5e_post_rx_wqes. */
 }
 
 void mlx5e_close_rq(struct mlx5e_rq *rq)
@@ -1332,12 +1328,10 @@ void mlx5e_tx_disable_queue(struct netdev_queue *txq)
 
 static void mlx5e_deactivate_txqsq(struct mlx5e_txqsq *sq)
 {
-       struct mlx5e_channel *c = sq->channel;
        struct mlx5_wq_cyc *wq = &sq->wq;
 
        clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
-       /* prevent netif_tx_wake_queue */
-       napi_synchronize(&c->napi);
+       synchronize_rcu(); /* Sync with NAPI to prevent netif_tx_wake_queue. */
 
        mlx5e_tx_disable_queue(sq->txq);
 
@@ -1412,10 +1406,8 @@ void mlx5e_activate_icosq(struct mlx5e_icosq *icosq)
 
 void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq)
 {
-       struct mlx5e_channel *c = icosq->channel;
-
        clear_bit(MLX5E_SQ_STATE_ENABLED, &icosq->state);
-       napi_synchronize(&c->napi);
+       synchronize_rcu(); /* Sync with NAPI. */
 }
 
 void mlx5e_close_icosq(struct mlx5e_icosq *sq)
@@ -1494,7 +1486,7 @@ void mlx5e_close_xdpsq(struct mlx5e_xdpsq *sq)
        struct mlx5e_channel *c = sq->channel;
 
        clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
-       napi_synchronize(&c->napi);
+       synchronize_rcu(); /* Sync with NAPI. */
 
        mlx5e_destroy_sq(c->mdev, sq->sqn);
        mlx5e_free_xdpsq_descs(sq);
@@ -3591,6 +3583,7 @@ void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s)
 
                s->rx_packets   += rq_stats->packets + xskrq_stats->packets;
                s->rx_bytes     += rq_stats->bytes + xskrq_stats->bytes;
+               s->multicast    += rq_stats->mcast_packets + xskrq_stats->mcast_packets;
 
                for (j = 0; j < priv->max_opened_tc; j++) {
                        struct mlx5e_sq_stats *sq_stats = &channel_stats->sq[j];
@@ -3606,7 +3599,6 @@ void
 mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
 {
        struct mlx5e_priv *priv = netdev_priv(dev);
-       struct mlx5e_vport_stats *vstats = &priv->stats.vport;
        struct mlx5e_pport_stats *pstats = &priv->stats.pport;
 
        /* In switchdev mode, monitor counters doesn't monitor
@@ -3641,12 +3633,6 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
        stats->rx_errors = stats->rx_length_errors + stats->rx_crc_errors +
                           stats->rx_frame_errors;
        stats->tx_errors = stats->tx_aborted_errors + stats->tx_carrier_errors;
-
-       /* vport multicast also counts packets that are dropped due to steering
-        * or rx out of buffer
-        */
-       stats->multicast =
-               VPORT_COUNTER_GET(vstats, received_eth_multicast.packets);
 }
 
 static void mlx5e_set_rx_mode(struct net_device *dev)
@@ -4355,6 +4341,16 @@ static int mlx5e_xdp_allowed(struct mlx5e_priv *priv, struct bpf_prog *prog)
        return 0;
 }
 
+static void mlx5e_rq_replace_xdp_prog(struct mlx5e_rq *rq, struct bpf_prog *prog)
+{
+       struct bpf_prog *old_prog;
+
+       old_prog = rcu_replace_pointer(rq->xdp_prog, prog,
+                                      lockdep_is_held(&rq->channel->priv->state_lock));
+       if (old_prog)
+               bpf_prog_put(old_prog);
+}
+
 static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog)
 {
        struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -4413,29 +4409,10 @@ static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog)
         */
        for (i = 0; i < priv->channels.num; i++) {
                struct mlx5e_channel *c = priv->channels.c[i];
-               bool xsk_open = test_bit(MLX5E_CHANNEL_STATE_XSK, c->state);
-
-               clear_bit(MLX5E_RQ_STATE_ENABLED, &c->rq.state);
-               if (xsk_open)
-                       clear_bit(MLX5E_RQ_STATE_ENABLED, &c->xskrq.state);
-               napi_synchronize(&c->napi);
-               /* prevent mlx5e_poll_rx_cq from accessing rq->xdp_prog */
-
-               old_prog = xchg(&c->rq.xdp_prog, prog);
-               if (old_prog)
-                       bpf_prog_put(old_prog);
-
-               if (xsk_open) {
-                       old_prog = xchg(&c->xskrq.xdp_prog, prog);
-                       if (old_prog)
-                               bpf_prog_put(old_prog);
-               }
 
-               set_bit(MLX5E_RQ_STATE_ENABLED, &c->rq.state);
-               if (xsk_open)
-                       set_bit(MLX5E_RQ_STATE_ENABLED, &c->xskrq.state);
-               /* napi_schedule in case we have missed anything */
-               napi_schedule(&c->napi);
+               mlx5e_rq_replace_xdp_prog(&c->rq, prog);
+               if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state))
+                       mlx5e_rq_replace_xdp_prog(&c->xskrq, prog);
        }
 
 unlock:
@@ -5227,7 +5204,7 @@ static const struct mlx5e_profile mlx5e_nic_profile = {
        .enable            = mlx5e_nic_enable,
        .disable           = mlx5e_nic_disable,
        .update_rx         = mlx5e_update_nic_rx,
-       .update_stats      = mlx5e_update_ndo_stats,
+       .update_stats      = mlx5e_stats_update_ndo_stats,
        .update_carrier    = mlx5e_update_carrier,
        .rx_handlers       = &mlx5e_rx_handlers_nic,
        .max_tc            = MLX5E_MAX_NUM_TC,