Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6da410d9 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'mlx5e-fixes-2018-09-05' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux



Saeed Mahameed says:

====================
Mellanox, mlx5 fixes 2018-09-05

This pull request contains some fixes for mlx5 etherent netdevice and
core driver.

Please pull and let me know if there's any problem.

For -stable v4.9:
('net/mlx5: Fix debugfs cleanup in the device init/remove flow')

For -stable v4.12:
("net/mlx5: E-Switch, Fix memory leak when creating switchdev mode FDB tables")

For -stable v4.13:
("net/mlx5: Fix use-after-free in self-healing flow")

For -stable v4.14:
("net/mlx5: Check for error in mlx5_attach_interface")

For -stable v4.15:
("net/mlx5: Fix not releasing read lock when adding flow rules")

For -stable v4.17:
("net/mlx5: Fix possible deadlock from lockdep when adding fte to fg")

For -stable v4.18:
("net/mlx5: Use u16 for Work Queue buffer fragment size")
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents fce471e3 ad9421e3
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -132,11 +132,11 @@ void mlx5_add_device(struct mlx5_interface *intf, struct mlx5_priv *priv)
	delayed_event_start(priv);

	dev_ctx->context = intf->add(dev);
	if (dev_ctx->context) {
		set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state);
		if (intf->attach)
			set_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state);

	if (dev_ctx->context) {
		spin_lock_irq(&priv->ctx_lock);
		list_add_tail(&dev_ctx->list, &priv->ctx_list);

@@ -211,12 +211,17 @@ static void mlx5_attach_interface(struct mlx5_interface *intf, struct mlx5_priv
	if (intf->attach) {
		if (test_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state))
			goto out;
		intf->attach(dev, dev_ctx->context);
		if (intf->attach(dev, dev_ctx->context))
			goto out;

		set_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state);
	} else {
		if (test_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state))
			goto out;
		dev_ctx->context = intf->add(dev);
		if (!dev_ctx->context)
			goto out;

		set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state);
	}

@@ -391,16 +396,17 @@ void mlx5_remove_dev_by_protocol(struct mlx5_core_dev *dev, int protocol)
		}
}

static u16 mlx5_gen_pci_id(struct mlx5_core_dev *dev)
static u32 mlx5_gen_pci_id(struct mlx5_core_dev *dev)
{
	return (u16)((dev->pdev->bus->number << 8) |
	return (u32)((pci_domain_nr(dev->pdev->bus) << 16) |
		     (dev->pdev->bus->number << 8) |
		     PCI_SLOT(dev->pdev->devfn));
}

/* Must be called with intf_mutex held */
struct mlx5_core_dev *mlx5_get_next_phys_dev(struct mlx5_core_dev *dev)
{
	u16 pci_id = mlx5_gen_pci_id(dev);
	u32 pci_id = mlx5_gen_pci_id(dev);
	struct mlx5_core_dev *res = NULL;
	struct mlx5_core_dev *tmp_dev;
	struct mlx5_priv *priv;
+1 −1
Original line number Diff line number Diff line
@@ -191,7 +191,7 @@ set_udp(void *headers_c, void *headers_v, __be16 psrc_m, __be16 psrc_v,
{
	if (psrc_m) {
		MLX5E_FTE_SET(headers_c, udp_sport, 0xffff);
		MLX5E_FTE_SET(headers_c, udp_sport, ntohs(psrc_v));
		MLX5E_FTE_SET(headers_v, udp_sport, ntohs(psrc_v));
	}

	if (pdst_m) {
+1 −0
Original line number Diff line number Diff line
@@ -663,6 +663,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
	if (err)
		goto miss_rule_err;

	kvfree(flow_group_in);
	return 0;

miss_rule_err:
+39 −37
Original line number Diff line number Diff line
@@ -1578,6 +1578,33 @@ static u64 matched_fgs_get_version(struct list_head *match_head)
	return version;
}

static struct fs_fte *
lookup_fte_locked(struct mlx5_flow_group *g,
		  u32 *match_value,
		  bool take_write)
{
	struct fs_fte *fte_tmp;

	if (take_write)
		nested_down_write_ref_node(&g->node, FS_LOCK_PARENT);
	else
		nested_down_read_ref_node(&g->node, FS_LOCK_PARENT);
	fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, match_value,
					 rhash_fte);
	if (!fte_tmp || !tree_get_node(&fte_tmp->node)) {
		fte_tmp = NULL;
		goto out;
	}

	nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD);
out:
	if (take_write)
		up_write_ref_node(&g->node);
	else
		up_read_ref_node(&g->node);
	return fte_tmp;
}

static struct mlx5_flow_handle *
try_add_to_existing_fg(struct mlx5_flow_table *ft,
		       struct list_head *match_head,
@@ -1600,10 +1627,6 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
	if (IS_ERR(fte))
		return  ERR_PTR(-ENOMEM);

	list_for_each_entry(iter, match_head, list) {
		nested_down_read_ref_node(&iter->g->node, FS_LOCK_PARENT);
	}

search_again_locked:
	version = matched_fgs_get_version(match_head);
	/* Try to find a fg that already contains a matching fte */
@@ -1611,20 +1634,9 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
		struct fs_fte *fte_tmp;

		g = iter->g;
		fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, spec->match_value,
						 rhash_fte);
		if (!fte_tmp || !tree_get_node(&fte_tmp->node))
		fte_tmp = lookup_fte_locked(g, spec->match_value, take_write);
		if (!fte_tmp)
			continue;

		nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD);
		if (!take_write) {
			list_for_each_entry(iter, match_head, list)
				up_read_ref_node(&iter->g->node);
		} else {
			list_for_each_entry(iter, match_head, list)
				up_write_ref_node(&iter->g->node);
		}

		rule = add_rule_fg(g, spec->match_value,
				   flow_act, dest, dest_num, fte_tmp);
		up_write_ref_node(&fte_tmp->node);
@@ -1633,19 +1645,6 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
		return rule;
	}

	/* No group with matching fte found. Try to add a new fte to any
	 * matching fg.
	 */

	if (!take_write) {
		list_for_each_entry(iter, match_head, list)
			up_read_ref_node(&iter->g->node);
		list_for_each_entry(iter, match_head, list)
			nested_down_write_ref_node(&iter->g->node,
						   FS_LOCK_PARENT);
		take_write = true;
	}

	/* Check the ft version, for case that new flow group
	 * was added while the fgs weren't locked
	 */
@@ -1657,27 +1656,30 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
	/* Check the fgs version, for case the new FTE with the
	 * same values was added while the fgs weren't locked
	 */
	if (version != matched_fgs_get_version(match_head))
	if (version != matched_fgs_get_version(match_head)) {
		take_write = true;
		goto search_again_locked;
	}

	list_for_each_entry(iter, match_head, list) {
		g = iter->g;

		if (!g->node.active)
			continue;

		nested_down_write_ref_node(&g->node, FS_LOCK_PARENT);

		err = insert_fte(g, fte);
		if (err) {
			up_write_ref_node(&g->node);
			if (err == -ENOSPC)
				continue;
			list_for_each_entry(iter, match_head, list)
				up_write_ref_node(&iter->g->node);
			kmem_cache_free(steering->ftes_cache, fte);
			return ERR_PTR(err);
		}

		nested_down_write_ref_node(&fte->node, FS_LOCK_CHILD);
		list_for_each_entry(iter, match_head, list)
			up_write_ref_node(&iter->g->node);
		up_write_ref_node(&g->node);
		rule = add_rule_fg(g, spec->match_value,
				   flow_act, dest, dest_num, fte);
		up_write_ref_node(&fte->node);
@@ -1686,8 +1688,6 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
	}
	rule = ERR_PTR(-ENOENT);
out:
	list_for_each_entry(iter, match_head, list)
		up_write_ref_node(&iter->g->node);
	kmem_cache_free(steering->ftes_cache, fte);
	return rule;
}
@@ -1726,6 +1726,8 @@ _mlx5_add_flow_rules(struct mlx5_flow_table *ft,
	if (err) {
		if (take_write)
			up_write_ref_node(&ft->node);
		else
			up_read_ref_node(&ft->node);
		return ERR_PTR(err);
	}

+9 −1
Original line number Diff line number Diff line
@@ -331,9 +331,17 @@ void mlx5_start_health_poll(struct mlx5_core_dev *dev)
	add_timer(&health->timer);
}

void mlx5_stop_health_poll(struct mlx5_core_dev *dev)
void mlx5_stop_health_poll(struct mlx5_core_dev *dev, bool disable_health)
{
	struct mlx5_core_health *health = &dev->priv.health;
	unsigned long flags;

	if (disable_health) {
		spin_lock_irqsave(&health->wq_lock, flags);
		set_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags);
		set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags);
		spin_unlock_irqrestore(&health->wq_lock, flags);
	}

	del_timer_sync(&health->timer);
}
Loading