Skip to content

Commit 6da410d

Browse files
committed
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: David S. Miller <[email protected]>
2 parents fce471e + ad9421e commit 6da410d

File tree

9 files changed

+79
-60
lines changed

9 files changed

+79
-60
lines changed

drivers/net/ethernet/mellanox/mlx5/core/dev.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,11 @@ void mlx5_add_device(struct mlx5_interface *intf, struct mlx5_priv *priv)
132132
delayed_event_start(priv);
133133

134134
dev_ctx->context = intf->add(dev);
135-
set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state);
136-
if (intf->attach)
137-
set_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state);
138-
139135
if (dev_ctx->context) {
136+
set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state);
137+
if (intf->attach)
138+
set_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state);
139+
140140
spin_lock_irq(&priv->ctx_lock);
141141
list_add_tail(&dev_ctx->list, &priv->ctx_list);
142142

@@ -211,12 +211,17 @@ static void mlx5_attach_interface(struct mlx5_interface *intf, struct mlx5_priv
211211
if (intf->attach) {
212212
if (test_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state))
213213
goto out;
214-
intf->attach(dev, dev_ctx->context);
214+
if (intf->attach(dev, dev_ctx->context))
215+
goto out;
216+
215217
set_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state);
216218
} else {
217219
if (test_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state))
218220
goto out;
219221
dev_ctx->context = intf->add(dev);
222+
if (!dev_ctx->context)
223+
goto out;
224+
220225
set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state);
221226
}
222227

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

394-
static u16 mlx5_gen_pci_id(struct mlx5_core_dev *dev)
399+
static u32 mlx5_gen_pci_id(struct mlx5_core_dev *dev)
395400
{
396-
return (u16)((dev->pdev->bus->number << 8) |
401+
return (u32)((pci_domain_nr(dev->pdev->bus) << 16) |
402+
(dev->pdev->bus->number << 8) |
397403
PCI_SLOT(dev->pdev->devfn));
398404
}
399405

400406
/* Must be called with intf_mutex held */
401407
struct mlx5_core_dev *mlx5_get_next_phys_dev(struct mlx5_core_dev *dev)
402408
{
403-
u16 pci_id = mlx5_gen_pci_id(dev);
409+
u32 pci_id = mlx5_gen_pci_id(dev);
404410
struct mlx5_core_dev *res = NULL;
405411
struct mlx5_core_dev *tmp_dev;
406412
struct mlx5_priv *priv;

drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ set_udp(void *headers_c, void *headers_v, __be16 psrc_m, __be16 psrc_v,
191191
{
192192
if (psrc_m) {
193193
MLX5E_FTE_SET(headers_c, udp_sport, 0xffff);
194-
MLX5E_FTE_SET(headers_c, udp_sport, ntohs(psrc_v));
194+
MLX5E_FTE_SET(headers_v, udp_sport, ntohs(psrc_v));
195195
}
196196

197197
if (pdst_m) {

drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
663663
if (err)
664664
goto miss_rule_err;
665665

666+
kvfree(flow_group_in);
666667
return 0;
667668

668669
miss_rule_err:

drivers/net/ethernet/mellanox/mlx5/core/fs_core.c

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,6 +1578,33 @@ static u64 matched_fgs_get_version(struct list_head *match_head)
15781578
return version;
15791579
}
15801580

1581+
static struct fs_fte *
1582+
lookup_fte_locked(struct mlx5_flow_group *g,
1583+
u32 *match_value,
1584+
bool take_write)
1585+
{
1586+
struct fs_fte *fte_tmp;
1587+
1588+
if (take_write)
1589+
nested_down_write_ref_node(&g->node, FS_LOCK_PARENT);
1590+
else
1591+
nested_down_read_ref_node(&g->node, FS_LOCK_PARENT);
1592+
fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, match_value,
1593+
rhash_fte);
1594+
if (!fte_tmp || !tree_get_node(&fte_tmp->node)) {
1595+
fte_tmp = NULL;
1596+
goto out;
1597+
}
1598+
1599+
nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD);
1600+
out:
1601+
if (take_write)
1602+
up_write_ref_node(&g->node);
1603+
else
1604+
up_read_ref_node(&g->node);
1605+
return fte_tmp;
1606+
}
1607+
15811608
static struct mlx5_flow_handle *
15821609
try_add_to_existing_fg(struct mlx5_flow_table *ft,
15831610
struct list_head *match_head,
@@ -1600,31 +1627,16 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
16001627
if (IS_ERR(fte))
16011628
return ERR_PTR(-ENOMEM);
16021629

1603-
list_for_each_entry(iter, match_head, list) {
1604-
nested_down_read_ref_node(&iter->g->node, FS_LOCK_PARENT);
1605-
}
1606-
16071630
search_again_locked:
16081631
version = matched_fgs_get_version(match_head);
16091632
/* Try to find a fg that already contains a matching fte */
16101633
list_for_each_entry(iter, match_head, list) {
16111634
struct fs_fte *fte_tmp;
16121635

16131636
g = iter->g;
1614-
fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, spec->match_value,
1615-
rhash_fte);
1616-
if (!fte_tmp || !tree_get_node(&fte_tmp->node))
1637+
fte_tmp = lookup_fte_locked(g, spec->match_value, take_write);
1638+
if (!fte_tmp)
16171639
continue;
1618-
1619-
nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD);
1620-
if (!take_write) {
1621-
list_for_each_entry(iter, match_head, list)
1622-
up_read_ref_node(&iter->g->node);
1623-
} else {
1624-
list_for_each_entry(iter, match_head, list)
1625-
up_write_ref_node(&iter->g->node);
1626-
}
1627-
16281640
rule = add_rule_fg(g, spec->match_value,
16291641
flow_act, dest, dest_num, fte_tmp);
16301642
up_write_ref_node(&fte_tmp->node);
@@ -1633,19 +1645,6 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
16331645
return rule;
16341646
}
16351647

1636-
/* No group with matching fte found. Try to add a new fte to any
1637-
* matching fg.
1638-
*/
1639-
1640-
if (!take_write) {
1641-
list_for_each_entry(iter, match_head, list)
1642-
up_read_ref_node(&iter->g->node);
1643-
list_for_each_entry(iter, match_head, list)
1644-
nested_down_write_ref_node(&iter->g->node,
1645-
FS_LOCK_PARENT);
1646-
take_write = true;
1647-
}
1648-
16491648
/* Check the ft version, for case that new flow group
16501649
* was added while the fgs weren't locked
16511650
*/
@@ -1657,27 +1656,30 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
16571656
/* Check the fgs version, for case the new FTE with the
16581657
* same values was added while the fgs weren't locked
16591658
*/
1660-
if (version != matched_fgs_get_version(match_head))
1659+
if (version != matched_fgs_get_version(match_head)) {
1660+
take_write = true;
16611661
goto search_again_locked;
1662+
}
16621663

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

16661667
if (!g->node.active)
16671668
continue;
1669+
1670+
nested_down_write_ref_node(&g->node, FS_LOCK_PARENT);
1671+
16681672
err = insert_fte(g, fte);
16691673
if (err) {
1674+
up_write_ref_node(&g->node);
16701675
if (err == -ENOSPC)
16711676
continue;
1672-
list_for_each_entry(iter, match_head, list)
1673-
up_write_ref_node(&iter->g->node);
16741677
kmem_cache_free(steering->ftes_cache, fte);
16751678
return ERR_PTR(err);
16761679
}
16771680

16781681
nested_down_write_ref_node(&fte->node, FS_LOCK_CHILD);
1679-
list_for_each_entry(iter, match_head, list)
1680-
up_write_ref_node(&iter->g->node);
1682+
up_write_ref_node(&g->node);
16811683
rule = add_rule_fg(g, spec->match_value,
16821684
flow_act, dest, dest_num, fte);
16831685
up_write_ref_node(&fte->node);
@@ -1686,8 +1688,6 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
16861688
}
16871689
rule = ERR_PTR(-ENOENT);
16881690
out:
1689-
list_for_each_entry(iter, match_head, list)
1690-
up_write_ref_node(&iter->g->node);
16911691
kmem_cache_free(steering->ftes_cache, fte);
16921692
return rule;
16931693
}
@@ -1726,6 +1726,8 @@ _mlx5_add_flow_rules(struct mlx5_flow_table *ft,
17261726
if (err) {
17271727
if (take_write)
17281728
up_write_ref_node(&ft->node);
1729+
else
1730+
up_read_ref_node(&ft->node);
17291731
return ERR_PTR(err);
17301732
}
17311733

drivers/net/ethernet/mellanox/mlx5/core/health.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,17 @@ void mlx5_start_health_poll(struct mlx5_core_dev *dev)
331331
add_timer(&health->timer);
332332
}
333333

334-
void mlx5_stop_health_poll(struct mlx5_core_dev *dev)
334+
void mlx5_stop_health_poll(struct mlx5_core_dev *dev, bool disable_health)
335335
{
336336
struct mlx5_core_health *health = &dev->priv.health;
337+
unsigned long flags;
338+
339+
if (disable_health) {
340+
spin_lock_irqsave(&health->wq_lock, flags);
341+
set_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags);
342+
set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags);
343+
spin_unlock_irqrestore(&health->wq_lock, flags);
344+
}
337345

338346
del_timer_sync(&health->timer);
339347
}

drivers/net/ethernet/mellanox/mlx5/core/main.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -878,8 +878,10 @@ static int mlx5_pci_init(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
878878
priv->numa_node = dev_to_node(&dev->pdev->dev);
879879

880880
priv->dbg_root = debugfs_create_dir(dev_name(&pdev->dev), mlx5_debugfs_root);
881-
if (!priv->dbg_root)
881+
if (!priv->dbg_root) {
882+
dev_err(&pdev->dev, "Cannot create debugfs dir, aborting\n");
882883
return -ENOMEM;
884+
}
883885

884886
err = mlx5_pci_enable_device(dev);
885887
if (err) {
@@ -928,7 +930,7 @@ static void mlx5_pci_close(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
928930
pci_clear_master(dev->pdev);
929931
release_bar(dev->pdev);
930932
mlx5_pci_disable_device(dev);
931-
debugfs_remove(priv->dbg_root);
933+
debugfs_remove_recursive(priv->dbg_root);
932934
}
933935

934936
static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
@@ -1286,7 +1288,7 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
12861288
mlx5_cleanup_once(dev);
12871289

12881290
err_stop_poll:
1289-
mlx5_stop_health_poll(dev);
1291+
mlx5_stop_health_poll(dev, boot);
12901292
if (mlx5_cmd_teardown_hca(dev)) {
12911293
dev_err(&dev->pdev->dev, "tear_down_hca failed, skip cleanup\n");
12921294
goto out_err;
@@ -1346,7 +1348,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
13461348
mlx5_free_irq_vectors(dev);
13471349
if (cleanup)
13481350
mlx5_cleanup_once(dev);
1349-
mlx5_stop_health_poll(dev);
1351+
mlx5_stop_health_poll(dev, cleanup);
13501352
err = mlx5_cmd_teardown_hca(dev);
13511353
if (err) {
13521354
dev_err(&dev->pdev->dev, "tear_down_hca failed, skip cleanup\n");
@@ -1608,7 +1610,7 @@ static int mlx5_try_fast_unload(struct mlx5_core_dev *dev)
16081610
* with the HCA, so the health polll is no longer needed.
16091611
*/
16101612
mlx5_drain_health_wq(dev);
1611-
mlx5_stop_health_poll(dev);
1613+
mlx5_stop_health_poll(dev, false);
16121614

16131615
ret = mlx5_cmd_force_teardown_hca(dev);
16141616
if (ret) {

drivers/net/ethernet/mellanox/mlx5/core/wq.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq)
3939
return (u32)wq->fbc.sz_m1 + 1;
4040
}
4141

42-
u32 mlx5_wq_cyc_get_frag_size(struct mlx5_wq_cyc *wq)
42+
u16 mlx5_wq_cyc_get_frag_size(struct mlx5_wq_cyc *wq)
4343
{
44-
return (u32)wq->fbc.frag_sz_m1 + 1;
44+
return wq->fbc.frag_sz_m1 + 1;
4545
}
4646

4747
u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq)
@@ -138,7 +138,7 @@ int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
138138
void *qpc, struct mlx5_wq_qp *wq,
139139
struct mlx5_wq_ctrl *wq_ctrl)
140140
{
141-
u32 sq_strides_offset;
141+
u16 sq_strides_offset;
142142
u32 rq_pg_remainder;
143143
int err;
144144

drivers/net/ethernet/mellanox/mlx5/core/wq.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
8080
void *wqc, struct mlx5_wq_cyc *wq,
8181
struct mlx5_wq_ctrl *wq_ctrl);
8282
u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq);
83-
u32 mlx5_wq_cyc_get_frag_size(struct mlx5_wq_cyc *wq);
83+
u16 mlx5_wq_cyc_get_frag_size(struct mlx5_wq_cyc *wq);
8484

8585
int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
8686
void *qpc, struct mlx5_wq_qp *wq,

include/linux/mlx5/driver.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,8 @@ struct mlx5_frag_buf {
362362
struct mlx5_frag_buf_ctrl {
363363
struct mlx5_frag_buf frag_buf;
364364
u32 sz_m1;
365-
u32 frag_sz_m1;
366-
u32 strides_offset;
365+
u16 frag_sz_m1;
366+
u16 strides_offset;
367367
u8 log_sz;
368368
u8 log_stride;
369369
u8 log_frag_strides;
@@ -995,7 +995,7 @@ static inline u32 mlx5_base_mkey(const u32 key)
995995
}
996996

997997
static inline void mlx5_fill_fbc_offset(u8 log_stride, u8 log_sz,
998-
u32 strides_offset,
998+
u16 strides_offset,
999999
struct mlx5_frag_buf_ctrl *fbc)
10001000
{
10011001
fbc->log_stride = log_stride;
@@ -1052,7 +1052,7 @@ int mlx5_cmd_free_uar(struct mlx5_core_dev *dev, u32 uarn);
10521052
void mlx5_health_cleanup(struct mlx5_core_dev *dev);
10531053
int mlx5_health_init(struct mlx5_core_dev *dev);
10541054
void mlx5_start_health_poll(struct mlx5_core_dev *dev);
1055-
void mlx5_stop_health_poll(struct mlx5_core_dev *dev);
1055+
void mlx5_stop_health_poll(struct mlx5_core_dev *dev, bool disable_health);
10561056
void mlx5_drain_health_wq(struct mlx5_core_dev *dev);
10571057
void mlx5_trigger_health_work(struct mlx5_core_dev *dev);
10581058
void mlx5_drain_health_recovery(struct mlx5_core_dev *dev);

0 commit comments

Comments
 (0)