Commit 878c2d60 authored by Yizhen Fan's avatar Yizhen Fan Committed by fanyizhen1995
Browse files

ub: ubcore add tp table ops api



driver inclusion
category: feature
bugzilla: NA
CVE: NA

--------------------------------

Ubcore add tp table ops api, including:
- ubcore_add_tp_node: Add tp as a node in tp hash table. Return old tp
node if key already exists.
- ubcore_find_remove_tp: Find and remove the tp from table only if
it is unreferenced.
- ubcore_get_tptable: Get tp hash table.
- ubcore_put_tptable: Release the tp hash table.
- ubcore_add_tp_with_tpn: Create tp node with specific tp.
- ubcore_remove_tp_with_tpn: Destroy tp node with specific tp.

Signed-off-by: default avatarGuoxin Qian <qianguoxin@huawei.com>
Signed-off-by: default avatarYizhen Fan <fanyizhen@huawei.com>
parent 832e9fe8
Loading
Loading
Loading
Loading
+116 −0
Original line number Diff line number Diff line
@@ -40,6 +40,33 @@ void ubcore_remove_tp_node(struct ubcore_hash_table *ht, struct ubcore_tp_node *
	kfree(tp_node);
}

/* Find and remove the tp from table only if it is unreferenced */
struct ubcore_tp *ubcore_find_remove_tp(struct ubcore_hash_table *ht, uint32_t hash,
					const struct ubcore_tp_key *key)
{
	struct ubcore_tp_node *tp_node;
	struct ubcore_tp *tp = NULL;

	spin_lock(&ht->lock);
	if (ht->head == NULL) {
		spin_unlock(&ht->lock);
		return NULL;
	}
	tp_node = ubcore_hash_table_lookup_nolock(ht, hash, key);
	if (tp_node == NULL) {
		spin_unlock(&ht->lock);
		return NULL;
	}

	if (atomic_dec_return(&tp_node->tp->use_cnt) == 0) {
		tp = tp_node->tp;
		hlist_del(&tp_node->hnode);
		kfree(tp_node);
	}
	spin_unlock(&ht->lock);
	return tp;
}

struct ubcore_hash_table *ubcore_create_tptable(void)
{
	struct ubcore_ht_param p = { .size = UBCORE_HASH_TABLE_SIZE,
@@ -89,3 +116,92 @@ void ubcore_destroy_tptable(struct ubcore_hash_table **pp_ht)
	/* pair with kref_init */
	(void)kref_put(&ht->kref, ubcore_tptable_release);
}

struct ubcore_hash_table *ubcore_get_tptable(struct ubcore_hash_table *ht)
{
	if (ht == NULL)
		return NULL;

	kref_get(&ht->kref);
	return ht;
}

void ubcore_put_tptable(struct ubcore_hash_table *ht)
{
	if (ht == NULL)
		return;

	(void)kref_put(&ht->kref, ubcore_tptable_release);
}

struct ubcore_tp_node *ubcore_add_tp_node(struct ubcore_hash_table *ht, uint32_t hash,
					  const struct ubcore_tp_key *key, struct ubcore_tp *tp,
					  struct ubcore_ta *ta)
{
	struct ubcore_tp_node *new_tp_node;
	struct ubcore_tp_node *tp_node;

	new_tp_node = kzalloc(sizeof(struct ubcore_tp_node), GFP_KERNEL);
	if (new_tp_node == NULL)
		return NULL;


	new_tp_node->key = *key;
	new_tp_node->tp = tp;
	new_tp_node->ta = *ta;
	mutex_init(&new_tp_node->lock);

	spin_lock(&ht->lock);
	if (ht->head == NULL) {
		spin_unlock(&ht->lock);
		kfree(new_tp_node);
		return NULL;
	}
	tp_node = ubcore_hash_table_lookup_nolock(ht, hash, key);
	if (tp_node != NULL) {
		spin_unlock(&ht->lock);
		kfree(new_tp_node);
		return tp_node;
	}

	ubcore_hash_table_add_nolock(ht, &new_tp_node->hnode, hash);
	/* set private data for tp restore */
	tp->priv = new_tp_node;
	spin_unlock(&ht->lock);
	return new_tp_node;
}

struct ubcore_tp_node *ubcore_add_tp_with_tpn(struct ubcore_device *dev, struct ubcore_tp *tp)
{
	struct ubcore_tp_node *tp_node;
	int ret;

	tp_node = kzalloc(sizeof(struct ubcore_tp_node), GFP_KERNEL);
	if (tp_node == NULL)
		return NULL;

	tp_node->key.key_type = UBCORE_TP_KEY_TPN;
	tp_node->key.tpn = tp->tpn;
	tp_node->tp = tp;
	mutex_init(&tp_node->lock);

	ret = ubcore_hash_table_find_add(&dev->ht[UBCORE_HT_TP], &tp_node->hnode, tp->tpn);
	if (ret != 0) {
		ubcore_log_err("Failed to add tp with tpn %u to tp table", tp->tpn);
		kfree(tp_node);
		return NULL;
	}
	/* set private data to find tp node fast */
	tp->priv = tp_node;
	return tp_node;
}

struct ubcore_tp *ubcore_remove_tp_with_tpn(struct ubcore_device *dev, uint32_t tpn)
{
	struct ubcore_tp_key key;

	memset(&key, 0, sizeof(struct ubcore_tp_key));
	key.key_type = UBCORE_TP_KEY_TPN;
	key.tpn = tpn;
	return ubcore_find_remove_tp(&dev->ht[UBCORE_HT_TP], tpn, &key);
}
+12 −0
Original line number Diff line number Diff line
@@ -44,10 +44,22 @@ struct ubcore_tp_node {

void ubcore_init_tp_key_jetty_id(struct ubcore_tp_key *key, const struct ubcore_jetty_id *jetty_id);

/* Return old tp node if key already exists */
struct ubcore_tp_node *ubcore_add_tp_node(struct ubcore_hash_table *ht, uint32_t hash,
					  const struct ubcore_tp_key *key, struct ubcore_tp *tp,
					  struct ubcore_ta *ta);
void ubcore_remove_tp_node(struct ubcore_hash_table *ht, struct ubcore_tp_node *tp_node);
/* Find and remove the tp from table only if it is unreferenced */
struct ubcore_tp *ubcore_find_remove_tp(struct ubcore_hash_table *ht, uint32_t hash,
					const struct ubcore_tp_key *key);

/* TP table ops for devices that do not natively support RM */
struct ubcore_hash_table *ubcore_create_tptable(void);
void ubcore_destroy_tptable(struct ubcore_hash_table **pp_ht);
struct ubcore_hash_table *ubcore_get_tptable(struct ubcore_hash_table *ht);
void ubcore_put_tptable(struct ubcore_hash_table *ht);

struct ubcore_tp_node *ubcore_add_tp_with_tpn(struct ubcore_device *dev, struct ubcore_tp *tp);
struct ubcore_tp *ubcore_remove_tp_with_tpn(struct ubcore_device *dev, uint32_t tpn);

#endif