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

Commit 93fc9e1b authored by Yevgeny Petrilin's avatar Yevgeny Petrilin Committed by Roland Dreier
Browse files

mlx4_core: Support multiple pre-reserved QP regions



For ethernet support, we need to reserve QPs for the ethernet and
fibre channel driver.  The QPs are reserved at the end of the QP
table.  (This way we assure that they are aligned to their size)

We need to consider these reserved ranges in bitmap creation, so we
extend the mlx4 bitmap utility functions to allow reserved ranges at
both the bottom and the top of the range.

Signed-off-by: default avatarYevgeny Petrilin <yevgenyp@mellanox.co.il>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent a3cdcbfa
Loading
Loading
Loading
Loading
+18 −11
Original line number Diff line number Diff line
@@ -47,13 +47,16 @@ u32 mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap)

	obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last);
	if (obj >= bitmap->max) {
		bitmap->top = (bitmap->top + bitmap->max) & bitmap->mask;
		bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
				& bitmap->mask;
		obj = find_first_zero_bit(bitmap->table, bitmap->max);
	}

	if (obj < bitmap->max) {
		set_bit(obj, bitmap->table);
		bitmap->last = (obj + 1) & (bitmap->max - 1);
		bitmap->last = (obj + 1);
		if (bitmap->last == bitmap->max)
			bitmap->last = 0;
		obj |= bitmap->top;
	} else
		obj = -1;
@@ -109,9 +112,9 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
	obj = find_aligned_range(bitmap->table, bitmap->last,
				 bitmap->max, cnt, align);
	if (obj >= bitmap->max) {
		bitmap->top = (bitmap->top + bitmap->max) & bitmap->mask;
		obj = find_aligned_range(bitmap->table, 0,
					 bitmap->max,
		bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
				& bitmap->mask;
		obj = find_aligned_range(bitmap->table, 0, bitmap->max,
					 cnt, align);
	}

@@ -136,17 +139,19 @@ void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt)
{
	u32 i;

	obj &= bitmap->max - 1;
	obj &= bitmap->max + bitmap->reserved_top - 1;

	spin_lock(&bitmap->lock);
	for (i = 0; i < cnt; i++)
		clear_bit(obj + i, bitmap->table);
	bitmap->last = min(bitmap->last, obj);
	bitmap->top = (bitmap->top + bitmap->max) & bitmap->mask;
	bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
			& bitmap->mask;
	spin_unlock(&bitmap->lock);
}

int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, u32 reserved)
int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask,
		     u32 reserved_bot, u32 reserved_top)
{
	int i;

@@ -156,14 +161,16 @@ int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, u32 reserved

	bitmap->last = 0;
	bitmap->top  = 0;
	bitmap->max  = num;
	bitmap->max  = num - reserved_top;
	bitmap->mask = mask;
	bitmap->reserved_top = reserved_top;
	spin_lock_init(&bitmap->lock);
	bitmap->table = kzalloc(BITS_TO_LONGS(num) * sizeof (long), GFP_KERNEL);
	bitmap->table = kzalloc(BITS_TO_LONGS(bitmap->max) *
				sizeof (long), GFP_KERNEL);
	if (!bitmap->table)
		return -ENOMEM;

	for (i = 0; i < reserved; ++i)
	for (i = 0; i < reserved_bot; ++i)
		set_bit(i, bitmap->table);

	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -300,7 +300,7 @@ int mlx4_init_cq_table(struct mlx4_dev *dev)
	INIT_RADIX_TREE(&cq_table->tree, GFP_ATOMIC);

	err = mlx4_bitmap_init(&cq_table->bitmap, dev->caps.num_cqs,
			       dev->caps.num_cqs - 1, dev->caps.reserved_cqs);
			       dev->caps.num_cqs - 1, dev->caps.reserved_cqs, 0);
	if (err)
		return err;

+1 −1
Original line number Diff line number Diff line
@@ -558,7 +558,7 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
	int i;

	err = mlx4_bitmap_init(&priv->eq_table.bitmap, dev->caps.num_eqs,
			       dev->caps.num_eqs - 1, dev->caps.reserved_eqs);
			       dev->caps.num_eqs - 1, dev->caps.reserved_eqs, 0);
	if (err)
		return err;

+5 −0
Original line number Diff line number Diff line
@@ -357,6 +357,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
#define QUERY_PORT_MTU_OFFSET			0x01
#define QUERY_PORT_WIDTH_OFFSET			0x06
#define QUERY_PORT_MAX_GID_PKEY_OFFSET		0x07
#define QUERY_PORT_MAX_MACVLAN_OFFSET		0x0a
#define QUERY_PORT_MAX_VL_OFFSET		0x0b

		for (i = 1; i <= dev_cap->num_ports; ++i) {
@@ -374,6 +375,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
			dev_cap->max_pkeys[i]	   = 1 << (field & 0xf);
			MLX4_GET(field, outbox, QUERY_PORT_MAX_VL_OFFSET);
			dev_cap->max_vl[i]	   = field & 0xf;
			MLX4_GET(field, outbox, QUERY_PORT_MAX_MACVLAN_OFFSET);
			dev_cap->log_max_macs[i]  = field & 0xf;
			dev_cap->log_max_vlans[i] = field >> 4;

		}
	}

+2 −0
Original line number Diff line number Diff line
@@ -102,6 +102,8 @@ struct mlx4_dev_cap {
	u32 reserved_lkey;
	u64 max_icm_sz;
	int max_gso_sz;
	u8  log_max_macs[MLX4_MAX_PORTS + 1];
	u8  log_max_vlans[MLX4_MAX_PORTS + 1];
};

struct mlx4_adapter {
Loading