aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2013-11-03 03:03:25 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-04 16:19:08 -0500
commit146f3ef4a193f2e8cc826bed01a635861287df63 (patch)
treee43baf0db805f6f49f0c335fd5e868d7afc3946d
parenteb456a68c67224efa71e7ef5975cf36c91794695 (diff)
net/mlx4_core: Implement resource quota enforcement
Implements resource quota grant decision when resources are requested, for the following resources: QPs, CQs, SRQs, MPTs, MTTs, vlans, MACs, and Counters. When granting a resource, the quota system increases the allocated-count for that slave. When the slave later frees the resource, its allocated-count is reduced. A spinlock is used to protect the integrity of each resource's free-pool counter. (One slave may be in the process of being granted a resource while another slave has crashed, initiating cleanup of that slave's resource quotas). Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c185
2 files changed, 173 insertions, 13 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index e7eb86ecc6ea..e582a41a802b 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -505,6 +505,7 @@ struct slave_list {
505}; 505};
506 506
507struct resource_allocator { 507struct resource_allocator {
508 spinlock_t alloc_lock; /* protect quotas */
508 union { 509 union {
509 int res_reserved; 510 int res_reserved;
510 int res_port_rsvd[MLX4_MAX_PORTS]; 511 int res_port_rsvd[MLX4_MAX_PORTS];
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index cc5d6d0aad16..b1603e2287a7 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -284,6 +284,85 @@ static const char *ResourceType(enum mlx4_resource rt)
284} 284}
285 285
286static void rem_slave_vlans(struct mlx4_dev *dev, int slave); 286static void rem_slave_vlans(struct mlx4_dev *dev, int slave);
287static inline int mlx4_grant_resource(struct mlx4_dev *dev, int slave,
288 enum mlx4_resource res_type, int count,
289 int port)
290{
291 struct mlx4_priv *priv = mlx4_priv(dev);
292 struct resource_allocator *res_alloc =
293 &priv->mfunc.master.res_tracker.res_alloc[res_type];
294 int err = -EINVAL;
295 int allocated, free, reserved, guaranteed, from_free;
296
297 if (slave > dev->num_vfs)
298 return -EINVAL;
299
300 spin_lock(&res_alloc->alloc_lock);
301 allocated = (port > 0) ?
302 res_alloc->allocated[(port - 1) * (dev->num_vfs + 1) + slave] :
303 res_alloc->allocated[slave];
304 free = (port > 0) ? res_alloc->res_port_free[port - 1] :
305 res_alloc->res_free;
306 reserved = (port > 0) ? res_alloc->res_port_rsvd[port - 1] :
307 res_alloc->res_reserved;
308 guaranteed = res_alloc->guaranteed[slave];
309
310 if (allocated + count > res_alloc->quota[slave])
311 goto out;
312
313 if (allocated + count <= guaranteed) {
314 err = 0;
315 } else {
316 /* portion may need to be obtained from free area */
317 if (guaranteed - allocated > 0)
318 from_free = count - (guaranteed - allocated);
319 else
320 from_free = count;
321
322 if (free - from_free > reserved)
323 err = 0;
324 }
325
326 if (!err) {
327 /* grant the request */
328 if (port > 0) {
329 res_alloc->allocated[(port - 1) * (dev->num_vfs + 1) + slave] += count;
330 res_alloc->res_port_free[port - 1] -= count;
331 } else {
332 res_alloc->allocated[slave] += count;
333 res_alloc->res_free -= count;
334 }
335 }
336
337out:
338 spin_unlock(&res_alloc->alloc_lock);
339 return err;
340}
341
342static inline void mlx4_release_resource(struct mlx4_dev *dev, int slave,
343 enum mlx4_resource res_type, int count,
344 int port)
345{
346 struct mlx4_priv *priv = mlx4_priv(dev);
347 struct resource_allocator *res_alloc =
348 &priv->mfunc.master.res_tracker.res_alloc[res_type];
349
350 if (slave > dev->num_vfs)
351 return;
352
353 spin_lock(&res_alloc->alloc_lock);
354 if (port > 0) {
355 res_alloc->allocated[(port - 1) * (dev->num_vfs + 1) + slave] -= count;
356 res_alloc->res_port_free[port - 1] += count;
357 } else {
358 res_alloc->allocated[slave] -= count;
359 res_alloc->res_free += count;
360 }
361
362 spin_unlock(&res_alloc->alloc_lock);
363 return;
364}
365
287static inline void initialize_res_quotas(struct mlx4_dev *dev, 366static inline void initialize_res_quotas(struct mlx4_dev *dev,
288 struct resource_allocator *res_alloc, 367 struct resource_allocator *res_alloc,
289 enum mlx4_resource res_type, 368 enum mlx4_resource res_type,
@@ -373,6 +452,7 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev)
373 !res_alloc->allocated) 452 !res_alloc->allocated)
374 goto no_mem_err; 453 goto no_mem_err;
375 454
455 spin_lock_init(&res_alloc->alloc_lock);
376 for (t = 0; t < dev->num_vfs + 1; t++) { 456 for (t = 0; t < dev->num_vfs + 1; t++) {
377 switch (i) { 457 switch (i) {
378 case RES_QP: 458 case RES_QP:
@@ -1399,12 +1479,19 @@ static int qp_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1399 case RES_OP_RESERVE: 1479 case RES_OP_RESERVE:
1400 count = get_param_l(&in_param); 1480 count = get_param_l(&in_param);
1401 align = get_param_h(&in_param); 1481 align = get_param_h(&in_param);
1402 err = __mlx4_qp_reserve_range(dev, count, align, &base); 1482 err = mlx4_grant_resource(dev, slave, RES_QP, count, 0);
1403 if (err) 1483 if (err)
1404 return err; 1484 return err;
1405 1485
1486 err = __mlx4_qp_reserve_range(dev, count, align, &base);
1487 if (err) {
1488 mlx4_release_resource(dev, slave, RES_QP, count, 0);
1489 return err;
1490 }
1491
1406 err = add_res_range(dev, slave, base, count, RES_QP, 0); 1492 err = add_res_range(dev, slave, base, count, RES_QP, 0);
1407 if (err) { 1493 if (err) {
1494 mlx4_release_resource(dev, slave, RES_QP, count, 0);
1408 __mlx4_qp_release_range(dev, base, count); 1495 __mlx4_qp_release_range(dev, base, count);
1409 return err; 1496 return err;
1410 } 1497 }
@@ -1452,15 +1539,24 @@ static int mtt_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1452 return err; 1539 return err;
1453 1540
1454 order = get_param_l(&in_param); 1541 order = get_param_l(&in_param);
1542
1543 err = mlx4_grant_resource(dev, slave, RES_MTT, 1 << order, 0);
1544 if (err)
1545 return err;
1546
1455 base = __mlx4_alloc_mtt_range(dev, order); 1547 base = __mlx4_alloc_mtt_range(dev, order);
1456 if (base == -1) 1548 if (base == -1) {
1549 mlx4_release_resource(dev, slave, RES_MTT, 1 << order, 0);
1457 return -ENOMEM; 1550 return -ENOMEM;
1551 }
1458 1552
1459 err = add_res_range(dev, slave, base, 1, RES_MTT, order); 1553 err = add_res_range(dev, slave, base, 1, RES_MTT, order);
1460 if (err) 1554 if (err) {
1555 mlx4_release_resource(dev, slave, RES_MTT, 1 << order, 0);
1461 __mlx4_free_mtt_range(dev, base, order); 1556 __mlx4_free_mtt_range(dev, base, order);
1462 else 1557 } else {
1463 set_param_l(out_param, base); 1558 set_param_l(out_param, base);
1559 }
1464 1560
1465 return err; 1561 return err;
1466} 1562}
@@ -1475,13 +1571,20 @@ static int mpt_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1475 1571
1476 switch (op) { 1572 switch (op) {
1477 case RES_OP_RESERVE: 1573 case RES_OP_RESERVE:
1574 err = mlx4_grant_resource(dev, slave, RES_MPT, 1, 0);
1575 if (err)
1576 break;
1577
1478 index = __mlx4_mpt_reserve(dev); 1578 index = __mlx4_mpt_reserve(dev);
1479 if (index == -1) 1579 if (index == -1) {
1580 mlx4_release_resource(dev, slave, RES_MPT, 1, 0);
1480 break; 1581 break;
1582 }
1481 id = index & mpt_mask(dev); 1583 id = index & mpt_mask(dev);
1482 1584
1483 err = add_res_range(dev, slave, id, 1, RES_MPT, index); 1585 err = add_res_range(dev, slave, id, 1, RES_MPT, index);
1484 if (err) { 1586 if (err) {
1587 mlx4_release_resource(dev, slave, RES_MPT, 1, 0);
1485 __mlx4_mpt_release(dev, index); 1588 __mlx4_mpt_release(dev, index);
1486 break; 1589 break;
1487 } 1590 }
@@ -1515,12 +1618,19 @@ static int cq_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1515 1618
1516 switch (op) { 1619 switch (op) {
1517 case RES_OP_RESERVE_AND_MAP: 1620 case RES_OP_RESERVE_AND_MAP:
1518 err = __mlx4_cq_alloc_icm(dev, &cqn); 1621 err = mlx4_grant_resource(dev, slave, RES_CQ, 1, 0);
1519 if (err) 1622 if (err)
1520 break; 1623 break;
1521 1624
1625 err = __mlx4_cq_alloc_icm(dev, &cqn);
1626 if (err) {
1627 mlx4_release_resource(dev, slave, RES_CQ, 1, 0);
1628 break;
1629 }
1630
1522 err = add_res_range(dev, slave, cqn, 1, RES_CQ, 0); 1631 err = add_res_range(dev, slave, cqn, 1, RES_CQ, 0);
1523 if (err) { 1632 if (err) {
1633 mlx4_release_resource(dev, slave, RES_CQ, 1, 0);
1524 __mlx4_cq_free_icm(dev, cqn); 1634 __mlx4_cq_free_icm(dev, cqn);
1525 break; 1635 break;
1526 } 1636 }
@@ -1543,12 +1653,19 @@ static int srq_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1543 1653
1544 switch (op) { 1654 switch (op) {
1545 case RES_OP_RESERVE_AND_MAP: 1655 case RES_OP_RESERVE_AND_MAP:
1546 err = __mlx4_srq_alloc_icm(dev, &srqn); 1656 err = mlx4_grant_resource(dev, slave, RES_SRQ, 1, 0);
1547 if (err) 1657 if (err)
1548 break; 1658 break;
1549 1659
1660 err = __mlx4_srq_alloc_icm(dev, &srqn);
1661 if (err) {
1662 mlx4_release_resource(dev, slave, RES_SRQ, 1, 0);
1663 break;
1664 }
1665
1550 err = add_res_range(dev, slave, srqn, 1, RES_SRQ, 0); 1666 err = add_res_range(dev, slave, srqn, 1, RES_SRQ, 0);
1551 if (err) { 1667 if (err) {
1668 mlx4_release_resource(dev, slave, RES_SRQ, 1, 0);
1552 __mlx4_srq_free_icm(dev, srqn); 1669 __mlx4_srq_free_icm(dev, srqn);
1553 break; 1670 break;
1554 } 1671 }
@@ -1569,9 +1686,13 @@ static int mac_add_to_slave(struct mlx4_dev *dev, int slave, u64 mac, int port)
1569 struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; 1686 struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1570 struct mac_res *res; 1687 struct mac_res *res;
1571 1688
1689 if (mlx4_grant_resource(dev, slave, RES_MAC, 1, port))
1690 return -EINVAL;
1572 res = kzalloc(sizeof *res, GFP_KERNEL); 1691 res = kzalloc(sizeof *res, GFP_KERNEL);
1573 if (!res) 1692 if (!res) {
1693 mlx4_release_resource(dev, slave, RES_MAC, 1, port);
1574 return -ENOMEM; 1694 return -ENOMEM;
1695 }
1575 res->mac = mac; 1696 res->mac = mac;
1576 res->port = (u8) port; 1697 res->port = (u8) port;
1577 list_add_tail(&res->list, 1698 list_add_tail(&res->list,
@@ -1591,6 +1712,7 @@ static void mac_del_from_slave(struct mlx4_dev *dev, int slave, u64 mac,
1591 list_for_each_entry_safe(res, tmp, mac_list, list) { 1712 list_for_each_entry_safe(res, tmp, mac_list, list) {
1592 if (res->mac == mac && res->port == (u8) port) { 1713 if (res->mac == mac && res->port == (u8) port) {
1593 list_del(&res->list); 1714 list_del(&res->list);
1715 mlx4_release_resource(dev, slave, RES_MAC, 1, port);
1594 kfree(res); 1716 kfree(res);
1595 break; 1717 break;
1596 } 1718 }
@@ -1608,6 +1730,7 @@ static void rem_slave_macs(struct mlx4_dev *dev, int slave)
1608 list_for_each_entry_safe(res, tmp, mac_list, list) { 1730 list_for_each_entry_safe(res, tmp, mac_list, list) {
1609 list_del(&res->list); 1731 list_del(&res->list);
1610 __mlx4_unregister_mac(dev, res->port, res->mac); 1732 __mlx4_unregister_mac(dev, res->port, res->mac);
1733 mlx4_release_resource(dev, slave, RES_MAC, 1, res->port);
1611 kfree(res); 1734 kfree(res);
1612 } 1735 }
1613} 1736}
@@ -1656,9 +1779,13 @@ static int vlan_add_to_slave(struct mlx4_dev *dev, int slave, u16 vlan,
1656 } 1779 }
1657 } 1780 }
1658 1781
1782 if (mlx4_grant_resource(dev, slave, RES_VLAN, 1, port))
1783 return -EINVAL;
1659 res = kzalloc(sizeof(*res), GFP_KERNEL); 1784 res = kzalloc(sizeof(*res), GFP_KERNEL);
1660 if (!res) 1785 if (!res) {
1786 mlx4_release_resource(dev, slave, RES_VLAN, 1, port);
1661 return -ENOMEM; 1787 return -ENOMEM;
1788 }
1662 res->vlan = vlan; 1789 res->vlan = vlan;
1663 res->port = (u8) port; 1790 res->port = (u8) port;
1664 res->vlan_index = vlan_index; 1791 res->vlan_index = vlan_index;
@@ -1682,6 +1809,8 @@ static void vlan_del_from_slave(struct mlx4_dev *dev, int slave, u16 vlan,
1682 if (res->vlan == vlan && res->port == (u8) port) { 1809 if (res->vlan == vlan && res->port == (u8) port) {
1683 if (!--res->ref_count) { 1810 if (!--res->ref_count) {
1684 list_del(&res->list); 1811 list_del(&res->list);
1812 mlx4_release_resource(dev, slave, RES_VLAN,
1813 1, port);
1685 kfree(res); 1814 kfree(res);
1686 } 1815 }
1687 break; 1816 break;
@@ -1703,6 +1832,7 @@ static void rem_slave_vlans(struct mlx4_dev *dev, int slave)
1703 /* dereference the vlan the num times the slave referenced it */ 1832 /* dereference the vlan the num times the slave referenced it */
1704 for (i = 0; i < res->ref_count; i++) 1833 for (i = 0; i < res->ref_count; i++)
1705 __mlx4_unregister_vlan(dev, res->port, res->vlan); 1834 __mlx4_unregister_vlan(dev, res->port, res->vlan);
1835 mlx4_release_resource(dev, slave, RES_VLAN, 1, res->port);
1706 kfree(res); 1836 kfree(res);
1707 } 1837 }
1708} 1838}
@@ -1749,15 +1879,23 @@ static int counter_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1749 if (op != RES_OP_RESERVE) 1879 if (op != RES_OP_RESERVE)
1750 return -EINVAL; 1880 return -EINVAL;
1751 1881
1752 err = __mlx4_counter_alloc(dev, &index); 1882 err = mlx4_grant_resource(dev, slave, RES_COUNTER, 1, 0);
1753 if (err) 1883 if (err)
1754 return err; 1884 return err;
1755 1885
1886 err = __mlx4_counter_alloc(dev, &index);
1887 if (err) {
1888 mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
1889 return err;
1890 }
1891
1756 err = add_res_range(dev, slave, index, 1, RES_COUNTER, 0); 1892 err = add_res_range(dev, slave, index, 1, RES_COUNTER, 0);
1757 if (err) 1893 if (err) {
1758 __mlx4_counter_free(dev, index); 1894 __mlx4_counter_free(dev, index);
1759 else 1895 mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
1896 } else {
1760 set_param_l(out_param, index); 1897 set_param_l(out_param, index);
1898 }
1761 1899
1762 return err; 1900 return err;
1763} 1901}
@@ -1864,6 +2002,7 @@ static int qp_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1864 err = rem_res_range(dev, slave, base, count, RES_QP, 0); 2002 err = rem_res_range(dev, slave, base, count, RES_QP, 0);
1865 if (err) 2003 if (err)
1866 break; 2004 break;
2005 mlx4_release_resource(dev, slave, RES_QP, count, 0);
1867 __mlx4_qp_release_range(dev, base, count); 2006 __mlx4_qp_release_range(dev, base, count);
1868 break; 2007 break;
1869 case RES_OP_MAP_ICM: 2008 case RES_OP_MAP_ICM:
@@ -1901,8 +2040,10 @@ static int mtt_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1901 base = get_param_l(&in_param); 2040 base = get_param_l(&in_param);
1902 order = get_param_h(&in_param); 2041 order = get_param_h(&in_param);
1903 err = rem_res_range(dev, slave, base, 1, RES_MTT, order); 2042 err = rem_res_range(dev, slave, base, 1, RES_MTT, order);
1904 if (!err) 2043 if (!err) {
2044 mlx4_release_resource(dev, slave, RES_MTT, 1 << order, 0);
1905 __mlx4_free_mtt_range(dev, base, order); 2045 __mlx4_free_mtt_range(dev, base, order);
2046 }
1906 return err; 2047 return err;
1907} 2048}
1908 2049
@@ -1927,6 +2068,7 @@ static int mpt_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1927 err = rem_res_range(dev, slave, id, 1, RES_MPT, 0); 2068 err = rem_res_range(dev, slave, id, 1, RES_MPT, 0);
1928 if (err) 2069 if (err)
1929 break; 2070 break;
2071 mlx4_release_resource(dev, slave, RES_MPT, 1, 0);
1930 __mlx4_mpt_release(dev, index); 2072 __mlx4_mpt_release(dev, index);
1931 break; 2073 break;
1932 case RES_OP_MAP_ICM: 2074 case RES_OP_MAP_ICM:
@@ -1961,6 +2103,7 @@ static int cq_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1961 if (err) 2103 if (err)
1962 break; 2104 break;
1963 2105
2106 mlx4_release_resource(dev, slave, RES_CQ, 1, 0);
1964 __mlx4_cq_free_icm(dev, cqn); 2107 __mlx4_cq_free_icm(dev, cqn);
1965 break; 2108 break;
1966 2109
@@ -1985,6 +2128,7 @@ static int srq_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1985 if (err) 2128 if (err)
1986 break; 2129 break;
1987 2130
2131 mlx4_release_resource(dev, slave, RES_SRQ, 1, 0);
1988 __mlx4_srq_free_icm(dev, srqn); 2132 __mlx4_srq_free_icm(dev, srqn);
1989 break; 2133 break;
1990 2134
@@ -2056,6 +2200,7 @@ static int counter_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
2056 return err; 2200 return err;
2057 2201
2058 __mlx4_counter_free(dev, index); 2202 __mlx4_counter_free(dev, index);
2203 mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
2059 2204
2060 return err; 2205 return err;
2061} 2206}
@@ -3785,6 +3930,11 @@ static void rem_slave_qps(struct mlx4_dev *dev, int slave)
3785 &tracker->res_tree[RES_QP]); 3930 &tracker->res_tree[RES_QP]);
3786 list_del(&qp->com.list); 3931 list_del(&qp->com.list);
3787 spin_unlock_irq(mlx4_tlock(dev)); 3932 spin_unlock_irq(mlx4_tlock(dev));
3933 if (!valid_reserved(dev, slave, qpn)) {
3934 __mlx4_qp_release_range(dev, qpn, 1);
3935 mlx4_release_resource(dev, slave,
3936 RES_QP, 1, 0);
3937 }
3788 kfree(qp); 3938 kfree(qp);
3789 state = 0; 3939 state = 0;
3790 break; 3940 break;
@@ -3856,6 +4006,8 @@ static void rem_slave_srqs(struct mlx4_dev *dev, int slave)
3856 &tracker->res_tree[RES_SRQ]); 4006 &tracker->res_tree[RES_SRQ]);
3857 list_del(&srq->com.list); 4007 list_del(&srq->com.list);
3858 spin_unlock_irq(mlx4_tlock(dev)); 4008 spin_unlock_irq(mlx4_tlock(dev));
4009 mlx4_release_resource(dev, slave,
4010 RES_SRQ, 1, 0);
3859 kfree(srq); 4011 kfree(srq);
3860 state = 0; 4012 state = 0;
3861 break; 4013 break;
@@ -3922,6 +4074,8 @@ static void rem_slave_cqs(struct mlx4_dev *dev, int slave)
3922 &tracker->res_tree[RES_CQ]); 4074 &tracker->res_tree[RES_CQ]);
3923 list_del(&cq->com.list); 4075 list_del(&cq->com.list);
3924 spin_unlock_irq(mlx4_tlock(dev)); 4076 spin_unlock_irq(mlx4_tlock(dev));
4077 mlx4_release_resource(dev, slave,
4078 RES_CQ, 1, 0);
3925 kfree(cq); 4079 kfree(cq);
3926 state = 0; 4080 state = 0;
3927 break; 4081 break;
@@ -3985,6 +4139,8 @@ static void rem_slave_mrs(struct mlx4_dev *dev, int slave)
3985 &tracker->res_tree[RES_MPT]); 4139 &tracker->res_tree[RES_MPT]);
3986 list_del(&mpt->com.list); 4140 list_del(&mpt->com.list);
3987 spin_unlock_irq(mlx4_tlock(dev)); 4141 spin_unlock_irq(mlx4_tlock(dev));
4142 mlx4_release_resource(dev, slave,
4143 RES_MPT, 1, 0);
3988 kfree(mpt); 4144 kfree(mpt);
3989 state = 0; 4145 state = 0;
3990 break; 4146 break;
@@ -4054,6 +4210,8 @@ static void rem_slave_mtts(struct mlx4_dev *dev, int slave)
4054 &tracker->res_tree[RES_MTT]); 4210 &tracker->res_tree[RES_MTT]);
4055 list_del(&mtt->com.list); 4211 list_del(&mtt->com.list);
4056 spin_unlock_irq(mlx4_tlock(dev)); 4212 spin_unlock_irq(mlx4_tlock(dev));
4213 mlx4_release_resource(dev, slave, RES_MTT,
4214 1 << mtt->order, 0);
4057 kfree(mtt); 4215 kfree(mtt);
4058 state = 0; 4216 state = 0;
4059 break; 4217 break;
@@ -4212,6 +4370,7 @@ static void rem_slave_counters(struct mlx4_dev *dev, int slave)
4212 list_del(&counter->com.list); 4370 list_del(&counter->com.list);
4213 kfree(counter); 4371 kfree(counter);
4214 __mlx4_counter_free(dev, index); 4372 __mlx4_counter_free(dev, index);
4373 mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
4215 } 4374 }
4216 } 4375 }
4217 spin_unlock_irq(mlx4_tlock(dev)); 4376 spin_unlock_irq(mlx4_tlock(dev));