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

Commit 7e1a61b6 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mlx4'



Or Gerlitz says:

====================
mlx4 SRIOV fixes

The patch from Wei Yang is a designed fix to a regression introduced by earlier commit
of him. Jack added a fix to the resource management which we got from IBM.

Let's get that into 3.16-rc1 1st and later see to what stable version/s this should go.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f05d435b da1de8df
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -2757,7 +2757,7 @@ static struct pci_driver mlx4_driver = {
	.name		= DRV_NAME,
	.name		= DRV_NAME,
	.id_table	= mlx4_pci_table,
	.id_table	= mlx4_pci_table,
	.probe		= mlx4_init_one,
	.probe		= mlx4_init_one,
	.shutdown	= mlx4_remove_one,
	.shutdown	= __mlx4_remove_one,
	.remove		= mlx4_remove_one,
	.remove		= mlx4_remove_one,
	.err_handler    = &mlx4_err_handler,
	.err_handler    = &mlx4_err_handler,
};
};
+37 −4
Original line number Original line Diff line number Diff line
@@ -279,7 +279,7 @@ enum qp_transition {
};
};


/* For Debug uses */
/* For Debug uses */
static const char *ResourceType(enum mlx4_resource rt)
static const char *resource_str(enum mlx4_resource rt)
{
{
	switch (rt) {
	switch (rt) {
	case RES_QP: return "RES_QP";
	case RES_QP: return "RES_QP";
@@ -307,6 +307,7 @@ static inline int mlx4_grant_resource(struct mlx4_dev *dev, int slave,
		&priv->mfunc.master.res_tracker.res_alloc[res_type];
		&priv->mfunc.master.res_tracker.res_alloc[res_type];
	int err = -EINVAL;
	int err = -EINVAL;
	int allocated, free, reserved, guaranteed, from_free;
	int allocated, free, reserved, guaranteed, from_free;
	int from_rsvd;


	if (slave > dev->num_vfs)
	if (slave > dev->num_vfs)
		return -EINVAL;
		return -EINVAL;
@@ -321,11 +322,16 @@ static inline int mlx4_grant_resource(struct mlx4_dev *dev, int slave,
		res_alloc->res_reserved;
		res_alloc->res_reserved;
	guaranteed = res_alloc->guaranteed[slave];
	guaranteed = res_alloc->guaranteed[slave];


	if (allocated + count > res_alloc->quota[slave])
	if (allocated + count > res_alloc->quota[slave]) {
		mlx4_warn(dev, "VF %d port %d res %s: quota exceeded, count %d alloc %d quota %d\n",
			  slave, port, resource_str(res_type), count,
			  allocated, res_alloc->quota[slave]);
		goto out;
		goto out;
	}


	if (allocated + count <= guaranteed) {
	if (allocated + count <= guaranteed) {
		err = 0;
		err = 0;
		from_rsvd = count;
	} else {
	} else {
		/* portion may need to be obtained from free area */
		/* portion may need to be obtained from free area */
		if (guaranteed - allocated > 0)
		if (guaranteed - allocated > 0)
@@ -333,8 +339,14 @@ static inline int mlx4_grant_resource(struct mlx4_dev *dev, int slave,
		else
		else
			from_free = count;
			from_free = count;


		if (free - from_free > reserved)
		from_rsvd = count - from_free;

		if (free - from_free >= reserved)
			err = 0;
			err = 0;
		else
			mlx4_warn(dev, "VF %d port %d res %s: free pool empty, free %d from_free %d rsvd %d\n",
				  slave, port, resource_str(res_type), free,
				  from_free, reserved);
	}
	}


	if (!err) {
	if (!err) {
@@ -342,9 +354,11 @@ static inline int mlx4_grant_resource(struct mlx4_dev *dev, int slave,
		if (port > 0) {
		if (port > 0) {
			res_alloc->allocated[(port - 1) * (dev->num_vfs + 1) + slave] += count;
			res_alloc->allocated[(port - 1) * (dev->num_vfs + 1) + slave] += count;
			res_alloc->res_port_free[port - 1] -= count;
			res_alloc->res_port_free[port - 1] -= count;
			res_alloc->res_port_rsvd[port - 1] -= from_rsvd;
		} else {
		} else {
			res_alloc->allocated[slave] += count;
			res_alloc->allocated[slave] += count;
			res_alloc->res_free -= count;
			res_alloc->res_free -= count;
			res_alloc->res_reserved -= from_rsvd;
		}
		}
	}
	}


@@ -360,17 +374,36 @@ static inline void mlx4_release_resource(struct mlx4_dev *dev, int slave,
	struct mlx4_priv *priv = mlx4_priv(dev);
	struct mlx4_priv *priv = mlx4_priv(dev);
	struct resource_allocator *res_alloc =
	struct resource_allocator *res_alloc =
		&priv->mfunc.master.res_tracker.res_alloc[res_type];
		&priv->mfunc.master.res_tracker.res_alloc[res_type];
	int allocated, guaranteed, from_rsvd;


	if (slave > dev->num_vfs)
	if (slave > dev->num_vfs)
		return;
		return;


	spin_lock(&res_alloc->alloc_lock);
	spin_lock(&res_alloc->alloc_lock);

	allocated = (port > 0) ?
		res_alloc->allocated[(port - 1) * (dev->num_vfs + 1) + slave] :
		res_alloc->allocated[slave];
	guaranteed = res_alloc->guaranteed[slave];

	if (allocated - count >= guaranteed) {
		from_rsvd = 0;
	} else {
		/* portion may need to be returned to reserved area */
		if (allocated - guaranteed > 0)
			from_rsvd = count - (allocated - guaranteed);
		else
			from_rsvd = count;
	}

	if (port > 0) {
	if (port > 0) {
		res_alloc->allocated[(port - 1) * (dev->num_vfs + 1) + slave] -= count;
		res_alloc->allocated[(port - 1) * (dev->num_vfs + 1) + slave] -= count;
		res_alloc->res_port_free[port - 1] += count;
		res_alloc->res_port_free[port - 1] += count;
		res_alloc->res_port_rsvd[port - 1] += from_rsvd;
	} else {
	} else {
		res_alloc->allocated[slave] -= count;
		res_alloc->allocated[slave] -= count;
		res_alloc->res_free += count;
		res_alloc->res_free += count;
		res_alloc->res_reserved += from_rsvd;
	}
	}


	spin_unlock(&res_alloc->alloc_lock);
	spin_unlock(&res_alloc->alloc_lock);
@@ -4135,7 +4168,7 @@ static int _move_all_busy(struct mlx4_dev *dev, int slave,
					if (print)
					if (print)
						mlx4_dbg(dev,
						mlx4_dbg(dev,
							 "%s id 0x%llx is busy\n",
							 "%s id 0x%llx is busy\n",
							  ResourceType(type),
							  resource_str(type),
							  r->res_id);
							  r->res_id);
					++busy;
					++busy;
				} else {
				} else {