diff options
author | Jack Morgenstein <jackm@dev.mellanox.co.il> | 2013-11-03 03:03:25 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-11-04 16:19:08 -0500 |
commit | 146f3ef4a193f2e8cc826bed01a635861287df63 (patch) | |
tree | e43baf0db805f6f49f0c335fd5e868d7afc3946d | |
parent | eb456a68c67224efa71e7ef5975cf36c91794695 (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.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 185 |
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 | ||
507 | struct resource_allocator { | 507 | struct 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 | ||
286 | static void rem_slave_vlans(struct mlx4_dev *dev, int slave); | 286 | static void rem_slave_vlans(struct mlx4_dev *dev, int slave); |
287 | static 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 | |||
337 | out: | ||
338 | spin_unlock(&res_alloc->alloc_lock); | ||
339 | return err; | ||
340 | } | ||
341 | |||
342 | static 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 | |||
287 | static inline void initialize_res_quotas(struct mlx4_dev *dev, | 366 | static 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)); |