mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	ALSA: control: obsolete user_ctl_lock
At a previous commit, concurrent requests for TLV data are maintained exclusively between read requests and write/command requests. TLV callback handlers in each driver has no risk from concurrent access for reference/change. In current implementation, 'struct snd_card' has a mutex to control concurrent accesses to user-defined element sets. This commit obsoletes it. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
		
							parent
							
								
									4c8099e9ca
								
							
						
					
					
						commit
						30d8340b58
					
				
					 3 changed files with 14 additions and 28 deletions
				
			
		| 
						 | 
				
			
			@ -118,8 +118,6 @@ struct snd_card {
 | 
			
		|||
	int user_ctl_count;		/* count of all user controls */
 | 
			
		||||
	struct list_head controls;	/* all controls for this card */
 | 
			
		||||
	struct list_head ctl_files;	/* active control files */
 | 
			
		||||
	struct mutex user_ctl_lock;	/* protects user controls against
 | 
			
		||||
					   concurrent access */
 | 
			
		||||
 | 
			
		||||
	struct snd_info_entry *proc_root;	/* root for soundcard specific files */
 | 
			
		||||
	struct snd_info_entry *proc_id;	/* the card id */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1095,9 +1095,7 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
 | 
			
		|||
	char *src = ue->elem_data +
 | 
			
		||||
			snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&ue->card->user_ctl_lock);
 | 
			
		||||
	memcpy(&ucontrol->value, src, size);
 | 
			
		||||
	mutex_unlock(&ue->card->user_ctl_lock);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1110,11 +1108,9 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol,
 | 
			
		|||
	char *dst = ue->elem_data +
 | 
			
		||||
			snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&ue->card->user_ctl_lock);
 | 
			
		||||
	change = memcmp(&ucontrol->value, dst, size) != 0;
 | 
			
		||||
	if (change)
 | 
			
		||||
		memcpy(dst, &ucontrol->value, size);
 | 
			
		||||
	mutex_unlock(&ue->card->user_ctl_lock);
 | 
			
		||||
	return change;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1124,44 +1120,37 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
 | 
			
		|||
				 unsigned int __user *tlv)
 | 
			
		||||
{
 | 
			
		||||
	struct user_element *ue = kcontrol->private_data;
 | 
			
		||||
	int change = 0;
 | 
			
		||||
	void *new_data;
 | 
			
		||||
 | 
			
		||||
	if (op_flag == SNDRV_CTL_TLV_OP_WRITE) {
 | 
			
		||||
		int change;
 | 
			
		||||
		void *new_data;
 | 
			
		||||
 | 
			
		||||
		if (size > 1024 * 128)	/* sane value */
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
 | 
			
		||||
		new_data = memdup_user(tlv, size);
 | 
			
		||||
		if (IS_ERR(new_data))
 | 
			
		||||
			return PTR_ERR(new_data);
 | 
			
		||||
		mutex_lock(&ue->card->user_ctl_lock);
 | 
			
		||||
		change = ue->tlv_data_size != size;
 | 
			
		||||
		if (!change)
 | 
			
		||||
			change = memcmp(ue->tlv_data, new_data, size);
 | 
			
		||||
		kfree(ue->tlv_data);
 | 
			
		||||
		ue->tlv_data = new_data;
 | 
			
		||||
		ue->tlv_data_size = size;
 | 
			
		||||
		mutex_unlock(&ue->card->user_ctl_lock);
 | 
			
		||||
	} else {
 | 
			
		||||
		int ret = 0;
 | 
			
		||||
 | 
			
		||||
		mutex_lock(&ue->card->user_ctl_lock);
 | 
			
		||||
		if (!ue->tlv_data_size || !ue->tlv_data) {
 | 
			
		||||
			ret = -ENXIO;
 | 
			
		||||
			goto err_unlock;
 | 
			
		||||
		}
 | 
			
		||||
		if (size < ue->tlv_data_size) {
 | 
			
		||||
			ret = -ENOSPC;
 | 
			
		||||
			goto err_unlock;
 | 
			
		||||
		}
 | 
			
		||||
		return change;
 | 
			
		||||
	} else {
 | 
			
		||||
		if (!ue->tlv_data_size || !ue->tlv_data)
 | 
			
		||||
			return -ENXIO;
 | 
			
		||||
 | 
			
		||||
		if (size < ue->tlv_data_size)
 | 
			
		||||
			return -ENOSPC;
 | 
			
		||||
 | 
			
		||||
		if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size))
 | 
			
		||||
			ret = -EFAULT;
 | 
			
		||||
err_unlock:
 | 
			
		||||
		mutex_unlock(&ue->card->user_ctl_lock);
 | 
			
		||||
		if (ret)
 | 
			
		||||
			return ret;
 | 
			
		||||
			return -EFAULT;
 | 
			
		||||
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	return change;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int snd_ctl_elem_init_enum_names(struct user_element *ue)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -248,7 +248,6 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
 | 
			
		|||
	INIT_LIST_HEAD(&card->devices);
 | 
			
		||||
	init_rwsem(&card->controls_rwsem);
 | 
			
		||||
	rwlock_init(&card->ctl_files_rwlock);
 | 
			
		||||
	mutex_init(&card->user_ctl_lock);
 | 
			
		||||
	INIT_LIST_HEAD(&card->controls);
 | 
			
		||||
	INIT_LIST_HEAD(&card->ctl_files);
 | 
			
		||||
	spin_lock_init(&card->files_lock);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue