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

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

Merge branch 'net-sched-couple-of-fixes'



Jiri Pirko says:

====================
net: sched: couple of fixes

This patchset contains couple of fixes following-up the shared block
patchsets.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0f2d2b27 339c21d7
Loading
Loading
Loading
Loading
+12 −14
Original line number Diff line number Diff line
@@ -376,17 +376,12 @@ struct tcf_net {
static unsigned int tcf_net_id;

static int tcf_block_insert(struct tcf_block *block, struct net *net,
			    u32 block_index, struct netlink_ext_ack *extack)
			    struct netlink_ext_ack *extack)
{
	struct tcf_net *tn = net_generic(net, tcf_net_id);
	int err;

	err = idr_alloc_u32(&tn->idr, block, &block_index, block_index,
	return idr_alloc_u32(&tn->idr, block, &block->index, block->index,
			     GFP_KERNEL);
	if (err)
		return err;
	block->index = block_index;
	return 0;
}

static void tcf_block_remove(struct tcf_block *block, struct net *net)
@@ -397,6 +392,7 @@ static void tcf_block_remove(struct tcf_block *block, struct net *net)
}

static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q,
					  u32 block_index,
					  struct netlink_ext_ack *extack)
{
	struct tcf_block *block;
@@ -419,9 +415,12 @@ static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q,
		err = -ENOMEM;
		goto err_chain_create;
	}
	block->net = qdisc_net(q);
	block->refcnt = 1;
	block->net = net;
	block->index = block_index;

	/* Don't store q pointer for blocks which are shared */
	if (!tcf_block_shared(block))
		block->q = q;
	return block;

@@ -518,13 +517,12 @@ int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
	}

	if (!block) {
		block = tcf_block_create(net, q, extack);
		block = tcf_block_create(net, q, ei->block_index, extack);
		if (IS_ERR(block))
			return PTR_ERR(block);
		created = true;
		if (ei->block_index) {
			err = tcf_block_insert(block, net,
					       ei->block_index, extack);
		if (tcf_block_shared(block)) {
			err = tcf_block_insert(block, net, extack);
			if (err)
				goto err_block_insert;
		}
+20 −4
Original line number Diff line number Diff line
@@ -96,7 +96,7 @@ struct tc_u_hnode {

struct tc_u_common {
	struct tc_u_hnode __rcu	*hlist;
	struct tcf_block	*block;
	void			*ptr;
	int			refcnt;
	struct idr		handle_idr;
	struct hlist_node	hnode;
@@ -330,9 +330,25 @@ static struct hlist_head *tc_u_common_hash;
#define U32_HASH_SHIFT 10
#define U32_HASH_SIZE (1 << U32_HASH_SHIFT)

static void *tc_u_common_ptr(const struct tcf_proto *tp)
{
	struct tcf_block *block = tp->chain->block;

	/* The block sharing is currently supported only
	 * for classless qdiscs. In that case we use block
	 * for tc_u_common identification. In case the
	 * block is not shared, block->q is a valid pointer
	 * and we can use that. That works for classful qdiscs.
	 */
	if (tcf_block_shared(block))
		return block;
	else
		return block->q;
}

static unsigned int tc_u_hash(const struct tcf_proto *tp)
{
	return hash_ptr(tp->chain->block, U32_HASH_SHIFT);
	return hash_ptr(tc_u_common_ptr(tp), U32_HASH_SHIFT);
}

static struct tc_u_common *tc_u_common_find(const struct tcf_proto *tp)
@@ -342,7 +358,7 @@ static struct tc_u_common *tc_u_common_find(const struct tcf_proto *tp)

	h = tc_u_hash(tp);
	hlist_for_each_entry(tc, &tc_u_common_hash[h], hnode) {
		if (tc->block == tp->chain->block)
		if (tc->ptr == tc_u_common_ptr(tp))
			return tc;
	}
	return NULL;
@@ -371,7 +387,7 @@ static int u32_init(struct tcf_proto *tp)
			kfree(root_ht);
			return -ENOBUFS;
		}
		tp_c->block = tp->chain->block;
		tp_c->ptr = tc_u_common_ptr(tp);
		INIT_HLIST_NODE(&tp_c->hnode);
		idr_init(&tp_c->handle_idr);