Skip to content

Commit

Permalink
asoc: msm: use hashtable to check kcontrol
Browse files Browse the repository at this point in the history
use hashtabe instead of linear list to check kcontrol before
adding them for improving early audio KPI.

Change-Id: I7134816736e08e338c0f22a8ae283a0520aa847a
Signed-off-by: Raghu Bankapur <quic_rbankapu@quicinc.com>
  • Loading branch information
Raghu Bankapur authored and intel-lab-lkp committed May 29, 2022
1 parent 4dd9989 commit 244d3a3
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 19 deletions.
4 changes: 4 additions & 0 deletions include/sound/control.h
Expand Up @@ -70,6 +70,10 @@ struct snd_kcontrol_volatile {
struct snd_kcontrol {
struct list_head list; /* list of controls */
struct snd_ctl_elem_id id;
#ifdef CONFIG_SND_CTL_HASHTABLE
struct hlist_node hnode;
unsigned int knametoint; /* kctl name to uint, hash key value */
#endif
unsigned int count; /* count of same elements */
snd_kcontrol_info_t *info;
snd_kcontrol_get_t *get;
Expand Down
12 changes: 10 additions & 2 deletions include/sound/core.h
Expand Up @@ -14,7 +14,9 @@
#include <linux/pm.h> /* pm_message_t */
#include <linux/stringify.h>
#include <linux/printk.h>

#ifdef CONFIG_SND_CTL_HASHTABLE
#include <linux/hashtable.h>
#endif
/* number of supported soundcards */
#ifdef CONFIG_SND_DYNAMIC_MINORS
#define SNDRV_CARDS CONFIG_SND_MAX_CARDS
Expand All @@ -24,6 +26,10 @@

#define CONFIG_SND_MAJOR 116 /* standard configuration */

#ifdef CONFIG_SND_CTL_HASHTABLE
#define SND_CTL_HASH_TABLE_BITS 14 /* buckets numbers: 1 << 14 */
#endif

/* forward declarations */
struct pci_dev;
struct module;
Expand Down Expand Up @@ -103,7 +109,9 @@ struct snd_card {
size_t user_ctl_alloc_size; // current memory allocation by user controls.
struct list_head controls; /* all controls for this card */
struct list_head ctl_files; /* active control files */

#ifdef CONFIG_SND_CTL_HASHTABLE
DECLARE_HASHTABLE(ctl_htable, SND_CTL_HASH_TABLE_BITS);
#endif
struct snd_info_entry *proc_root; /* root for soundcard specific files */
struct proc_dir_entry *proc_root_link; /* number link to real id */

Expand Down
92 changes: 75 additions & 17 deletions sound/core/control.c
Expand Up @@ -368,6 +368,47 @@ enum snd_ctl_add_mode {
CTL_ADD_EXCLUSIVE, CTL_REPLACE, CTL_ADD_ON_REPLACE,
};

#ifdef CONFIG_SND_CTL_HASHTABLE
char snd_ctl_string[50] = { '\0' };

/* Used to convert the string into int value -- BKDRHash */
unsigned int snd_ctl_strtoint(const char *s)
{
unsigned int res = 0;

while (*s)
res = (res << 5) - res + (*s++);

return (res & 0x7FFFFFFF);
}

/**
* snd_ctl_hash_check - Check the duplicate enrty on snd hashtable
* @card: the card instance
* @nametoint: kctl name to uint
*
* Finds the control instance with the given nametoint from the card.
*
* Return: The pointer of the instance if found, or %NULL if not.
*
*/
static struct snd_kcontrol *snd_ctl_hash_check(struct snd_card *card,
unsigned int nametoint)
{
struct snd_kcontrol *kctl = NULL;

if (snd_BUG_ON(!card))
return NULL;

hash_for_each_possible(card->ctl_htable, kctl, hnode, nametoint) {
if (kctl->knametoint != nametoint)
continue;
return kctl;
}
return NULL;
}
#endif

/* add/replace a new kcontrol object; call with card->controls_rwsem locked */
static int __snd_ctl_add_replace(struct snd_card *card,
struct snd_kcontrol *kcontrol,
Expand All @@ -382,24 +423,38 @@ static int __snd_ctl_add_replace(struct snd_card *card,
if (id.index > UINT_MAX - kcontrol->count)
return -EINVAL;

old = snd_ctl_find_id(card, &id);
if (!old) {
if (mode == CTL_REPLACE)
return -EINVAL;
} else {
if (mode == CTL_ADD_EXCLUSIVE) {
dev_err(card->dev,
"control %i:%i:%i:%s:%i is already present\n",
id.iface, id.device, id.subdevice, id.name,
id.index);
return -EBUSY;
}
#ifdef CONFIG_SND_CTL_HASHTABLE
snprintf(snd_ctl_string, strlen(kcontrol->id.name) + 6, "%s%d%d%d",
kcontrol->id.name, kcontrol->id.iface, kcontrol->id.device,
kcontrol->id.subdevice);

err = snd_ctl_remove(card, old);
if (err < 0)
return err;
}
kcontrol->knametoint = snd_ctl_strtoint(snd_ctl_string);
if (kcontrol->knametoint < 0)
return -EINVAL;

old = snd_ctl_hash_check(card, kcontrol->knametoint);
if (old) {
#endif
old = snd_ctl_find_id(card, &id);
if (!old) {
if (mode == CTL_REPLACE)
return -EINVAL;
} else {
if (mode == CTL_ADD_EXCLUSIVE) {
dev_err(card->dev,
"control %i:%i:%i:%s:%i is already present\n",
id.iface, id.device, id.subdevice, id.name,
id.index);
return -EBUSY;
}

err = snd_ctl_remove(card, old);
if (err < 0)
return err;
}
#ifdef CONFIG_SND_CTL_HASHTABLE
}
#endif
if (snd_ctl_find_hole(card, kcontrol->count) < 0)
return -ENOMEM;

Expand All @@ -410,7 +465,10 @@ static int __snd_ctl_add_replace(struct snd_card *card,

for (idx = 0; idx < kcontrol->count; idx++)
snd_ctl_notify_one(card, SNDRV_CTL_EVENT_MASK_ADD, kcontrol, idx);


#ifdef CONFIG_SND_CTL_HASHTABLE
hash_add(card->ctl_htable, &kcontrol->hnode, kcontrol->knametoint);
#endif
return 0;
}

Expand Down
3 changes: 3 additions & 0 deletions sound/core/init.c
Expand Up @@ -312,6 +312,9 @@ static int snd_card_init(struct snd_card *card, struct device *parent,
INIT_LIST_HEAD(&card->ctl_files);
spin_lock_init(&card->files_lock);
INIT_LIST_HEAD(&card->files_list);
#ifdef CONFIG_SND_CTL_HASHTABLE
hash_init(card->ctl_htable);
#endif
mutex_init(&card->memory_mutex);
#ifdef CONFIG_PM
init_waitqueue_head(&card->power_sleep);
Expand Down
9 changes: 9 additions & 0 deletions sound/soc/Kconfig
Expand Up @@ -65,6 +65,15 @@ config SND_SOC_UTILS_KUNIT_TEST
config SND_SOC_ACPI
tristate

config SND_CTL_HASHTABLE
bool "Add SND CTL hashtable"
help
This enables hash table in sound card for kcontrols. The traditional way is
traversing the linked list of controls and compare each exsiting control with
the new kcontrol to find out whether there are duplicate kcontrols, which will
consumes much time during bootup. Enable this will use hash table instead of
linked list to check new kcontrol and reduce much time for sound card registration.

# All the supported SoCs
source "sound/soc/adi/Kconfig"
source "sound/soc/amd/Kconfig"
Expand Down

0 comments on commit 244d3a3

Please sign in to comment.