Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167407879
D59074.id184640.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D59074.id184640.diff
View Options
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -2170,14 +2170,14 @@
if (c->direction == PCMDIR_PLAY &&
(d->flags & SD_F_SOFTPCMVOL)) {
- /* CHN_UNLOCK(c); */
+ CHN_UNLOCK(c);
vol = mix_get(m, SOUND_MIXER_PCM);
parent = mix_getparent(m, SOUND_MIXER_PCM);
if (parent != SOUND_MIXER_NONE)
pvol = mix_get(m, parent);
else
pvol = 100 | (100 << 8);
- /* CHN_LOCK(c); */
+ CHN_LOCK(c);
} else {
vol = 100 | (100 << 8);
pvol = vol;
@@ -2208,10 +2208,10 @@
struct pcm_feeder *f;
int treble, bass;
- /* CHN_UNLOCK(c); */
+ CHN_UNLOCK(c);
treble = mix_get(m, SOUND_MIXER_TREBLE);
bass = mix_get(m, SOUND_MIXER_BASS);
- /* CHN_LOCK(c); */
+ CHN_LOCK(c);
if (treble == -1)
treble = 50;
diff --git a/sys/dev/sound/pcm/mixer.h b/sys/dev/sound/pcm/mixer.h
--- a/sys/dev/sound/pcm/mixer.h
+++ b/sys/dev/sound/pcm/mixer.h
@@ -54,7 +54,8 @@
uint32_t child[32];
uint8_t realdev[32];
char name[MIXER_NAMELEN];
- struct mtx lock;
+ struct mtx *lock;
+ struct mtx priv_lock;
int modify_counter;
struct cdev *cdev;
};
diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c
--- a/sys/dev/sound/pcm/mixer.c
+++ b/sys/dev/sound/pcm/mixer.c
@@ -97,46 +97,15 @@
return -1;
}
-#define MIXER_SET_UNLOCK(x, y) do { \
- if ((y) != 0) \
- mtx_unlock(&(x)->lock); \
-} while (0)
-
-#define MIXER_SET_LOCK(x, y) do { \
- if ((y) != 0) \
- mtx_lock(&(x)->lock); \
-} while (0)
-
static int
mixer_set_softpcmvol(struct snd_mixer *m, struct snddev_info *d,
unsigned int left, unsigned int right)
{
struct pcm_channel *c;
- int dropmtx, acquiremtx;
if (!PCM_REGISTERED(d))
return (EINVAL);
- if (mtx_owned(&m->lock))
- dropmtx = 1;
- else
- dropmtx = 0;
-
- if (!(d->flags & SD_F_MPSAFE) || mtx_owned(&d->lock) != 0)
- acquiremtx = 0;
- else
- acquiremtx = 1;
-
- /*
- * Be careful here. If we're coming from cdev ioctl, it is OK to
- * not doing locking AT ALL (except on individual channel) since
- * we've been heavily guarded by pcm cv, or if we're still
- * under Giant influence. Since we also have mix_* calls, we cannot
- * assume such protection and just do the lock as usuall.
- */
- MIXER_SET_UNLOCK(m, dropmtx);
- MIXER_SET_LOCK(d, acquiremtx);
-
CHN_FOREACH(c, d, channels.pcm.busy) {
CHN_LOCK(c);
if (c->direction == PCMDIR_PLAY &&
@@ -146,9 +115,6 @@
CHN_UNLOCK(c);
}
- MIXER_SET_UNLOCK(d, acquiremtx);
- MIXER_SET_LOCK(m, dropmtx);
-
return (0);
}
@@ -158,7 +124,7 @@
{
struct pcm_channel *c;
struct pcm_feeder *f;
- int tone, dropmtx, acquiremtx;
+ int tone;
if (dev == SOUND_MIXER_TREBLE)
tone = FEEDEQ_TREBLE;
@@ -170,26 +136,6 @@
if (!PCM_REGISTERED(d))
return (EINVAL);
- if (mtx_owned(&m->lock))
- dropmtx = 1;
- else
- dropmtx = 0;
-
- if (!(d->flags & SD_F_MPSAFE) || mtx_owned(&d->lock) != 0)
- acquiremtx = 0;
- else
- acquiremtx = 1;
-
- /*
- * Be careful here. If we're coming from cdev ioctl, it is OK to
- * not doing locking AT ALL (except on individual channel) since
- * we've been heavily guarded by pcm cv, or if we're still
- * under Giant influence. Since we also have mix_* calls, we cannot
- * assume such protection and just do the lock as usuall.
- */
- MIXER_SET_UNLOCK(m, dropmtx);
- MIXER_SET_LOCK(d, acquiremtx);
-
CHN_FOREACH(c, d, channels.pcm.busy) {
CHN_LOCK(c);
f = feeder_find(c, FEEDER_EQ);
@@ -198,9 +144,6 @@
CHN_UNLOCK(c);
}
- MIXER_SET_UNLOCK(d, acquiremtx);
- MIXER_SET_LOCK(m, dropmtx);
-
return (0);
}
@@ -211,7 +154,7 @@
unsigned int l, r, tl, tr;
uint32_t parent = SOUND_MIXER_NONE, child = 0;
uint32_t realdev;
- int i, dropmtx;
+ int i;
if (m == NULL || dev >= SOUND_MIXER_NRDEVICES ||
(0 == (m->devs & (1 << dev))))
@@ -225,18 +168,11 @@
if (d == NULL)
return (-1);
- /* It is safe to drop this mutex due to Giant. */
- if (!(d->flags & SD_F_MPSAFE) && mtx_owned(&m->lock) != 0)
- dropmtx = 1;
- else
- dropmtx = 0;
-
/* Allow the volume to be "changed" while muted. */
if (muted & (1 << dev)) {
m->level_muted[dev] = l | (r << 8);
return (0);
}
- MIXER_SET_UNLOCK(m, dropmtx);
/* TODO: recursive handling */
parent = m->parent[dev];
@@ -251,10 +187,8 @@
if (dev == SOUND_MIXER_PCM && (d->flags & SD_F_SOFTPCMVOL))
(void)mixer_set_softpcmvol(m, d, tl, tr);
else if (realdev != SOUND_MIXER_NONE &&
- MIXER_SET(m, realdev, tl, tr) < 0) {
- MIXER_SET_LOCK(m, dropmtx);
+ MIXER_SET(m, realdev, tl, tr) < 0)
return (-1);
- }
} else if (child != 0) {
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
if (!(child & (1 << i)) || m->parent[i] != dev)
@@ -270,10 +204,8 @@
}
realdev = m->realdev[dev];
if (realdev != SOUND_MIXER_NONE &&
- MIXER_SET(m, realdev, l, r) < 0) {
- MIXER_SET_LOCK(m, dropmtx);
+ MIXER_SET(m, realdev, l, r) < 0)
return (-1);
- }
} else {
if (dev == SOUND_MIXER_PCM && (d->flags & SD_F_SOFTPCMVOL))
(void)mixer_set_softpcmvol(m, d, l, r);
@@ -281,14 +213,10 @@
dev == SOUND_MIXER_BASS) && (d->flags & SD_F_EQ))
(void)mixer_set_eq(m, d, dev, (l + r) >> 1);
else if (realdev != SOUND_MIXER_NONE &&
- MIXER_SET(m, realdev, l, r) < 0) {
- MIXER_SET_LOCK(m, dropmtx);
+ MIXER_SET(m, realdev, l, r) < 0)
return (-1);
- }
}
- MIXER_SET_LOCK(m, dropmtx);
-
m->level[dev] = l | (r << 8);
m->modify_counter++;
@@ -335,15 +263,10 @@
{
struct snddev_info *d;
uint32_t recsrc;
- int dropmtx;
d = device_get_softc(mixer->dev);
if (d == NULL)
return -1;
- if (!(d->flags & SD_F_MPSAFE) && mtx_owned(&mixer->lock) != 0)
- dropmtx = 1;
- else
- dropmtx = 0;
src &= mixer->recdevs;
if (src == 0)
src = mixer->recdevs & SOUND_MASK_MIC;
@@ -353,10 +276,7 @@
src = mixer->recdevs & SOUND_MASK_LINE;
if (src == 0 && mixer->recdevs != 0)
src = (1 << (ffs(mixer->recdevs) - 1));
- /* It is safe to drop this mutex due to Giant. */
- MIXER_SET_UNLOCK(mixer, dropmtx);
recsrc = MIXER_SETRECSRC(mixer, src);
- MIXER_SET_LOCK(mixer, dropmtx);
mixer->recsrc = recsrc;
@@ -551,6 +471,7 @@
mixer_obj_create(device_t dev, kobj_class_t cls, void *devinfo,
int type, const char *desc)
{
+ struct snddev_info *d;
struct snd_mixer *m;
size_t i;
@@ -567,8 +488,14 @@
strlcat(m->name, ":", sizeof(m->name));
strlcat(m->name, desc, sizeof(m->name));
}
- mtx_init(&m->lock, m->name, (type == MIXER_TYPE_PRIMARY) ?
- "primary pcm mixer" : "secondary pcm mixer", MTX_DEF);
+
+ d = device_get_softc(dev);
+ if (type == MIXER_TYPE_PRIMARY)
+ m->lock = &d->lock;
+ else {
+ mtx_init(&m->priv_lock, m->name, "secondary pcm mixer", MTX_DEF);
+ m->lock = &m->priv_lock;
+ }
m->type = type;
m->devinfo = devinfo;
m->dev = dev;
@@ -579,7 +506,8 @@
}
if (MIXER_INIT(m)) {
- mtx_destroy(&m->lock);
+ if (type == MIXER_TYPE_SECONDARY)
+ mtx_destroy(m->lock);
kobj_delete((kobj_t)m, M_DEVBUF);
return (NULL);
}
@@ -598,7 +526,8 @@
MIXER_UNINIT(m);
- mtx_destroy(&m->lock);
+ if (m->type == MIXER_TYPE_SECONDARY)
+ mtx_destroy(m->lock);
kobj_delete((kobj_t)m, M_DEVBUF);
return (0);
@@ -695,20 +624,21 @@
if (MIXER_REGISTERED(m))
destroy_dev(m->cdev);
- mtx_lock(&m->lock);
+ mtx_lock(m->lock);
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
mixer_set(m, i, 0, 0);
mixer_setrecsrc(m, SOUND_MASK_MIC);
- mtx_unlock(&m->lock);
+ mtx_unlock(m->lock);
/* mixer uninit can sleep --hps */
MIXER_UNINIT(m);
- mtx_destroy(&m->lock);
+ if (m->type == MIXER_TYPE_SECONDARY)
+ mtx_destroy(m->lock);
kobj_delete((kobj_t)m, M_DEVBUF);
return 0;
@@ -721,11 +651,11 @@
int i;
m = mixer_get_devt(dev);
- mtx_lock(&m->lock);
+ mtx_lock(m->lock);
i = MIXER_REINIT(m);
if (i) {
- mtx_unlock(&m->lock);
+ mtx_unlock(m->lock);
return i;
}
@@ -737,7 +667,7 @@
}
mixer_setrecsrc(m, m->recsrc);
- mtx_unlock(&m->lock);
+ mtx_unlock(m->lock);
return 0;
}
@@ -776,21 +706,21 @@
struct snd_mixer *m;
m = oidp->oid_arg1;
- mtx_lock(&m->lock);
+ mtx_lock(m->lock);
strlcpy(devname, snd_mixernames[m->hwvol_mixer], sizeof(devname));
- mtx_unlock(&m->lock);
+ mtx_unlock(m->lock);
error = sysctl_handle_string(oidp, &devname[0], sizeof(devname), req);
- mtx_lock(&m->lock);
+ mtx_lock(m->lock);
if (error == 0 && req->newptr != NULL) {
dev = mixer_lookup(devname);
if (dev == -1) {
- mtx_unlock(&m->lock);
+ mtx_unlock(m->lock);
return EINVAL;
} else {
m->hwvol_mixer = dev;
}
}
- mtx_unlock(&m->lock);
+ mtx_unlock(m->lock);
return error;
}
@@ -825,9 +755,9 @@
struct snd_mixer *m;
m = mixer_get_devt(dev);
- mtx_lock(&m->lock);
+ mtx_lock(m->lock);
mixer_hwvol_mute_locked(m);
- mtx_unlock(&m->lock);
+ mtx_unlock(m->lock);
}
void
@@ -861,9 +791,9 @@
struct snd_mixer *m;
m = mixer_get_devt(dev);
- mtx_lock(&m->lock);
+ mtx_lock(m->lock);
mixer_hwvol_step_locked(m, left_step, right_step);
- mtx_unlock(&m->lock);
+ mtx_unlock(m->lock);
}
int
@@ -873,9 +803,9 @@
KASSERT(m != NULL, ("NULL snd_mixer"));
- mtx_lock(&m->lock);
+ mtx_lock(m->lock);
ret = mixer_set(m, dev, m->mutedevs, left | (right << 8));
- mtx_unlock(&m->lock);
+ mtx_unlock(m->lock);
return ((ret != 0) ? ENXIO : 0);
}
@@ -887,9 +817,9 @@
KASSERT(m != NULL, ("NULL snd_mixer"));
- mtx_lock(&m->lock);
+ mtx_lock(m->lock);
ret = mixer_get(m, dev);
- mtx_unlock(&m->lock);
+ mtx_unlock(m->lock);
return (ret);
}
@@ -901,9 +831,9 @@
KASSERT(m != NULL, ("NULL snd_mixer"));
- mtx_lock(&m->lock);
+ mtx_lock(m->lock);
ret = mixer_setrecsrc(m, src);
- mtx_unlock(&m->lock);
+ mtx_unlock(m->lock);
return ((ret != 0) ? ENXIO : 0);
}
@@ -915,9 +845,9 @@
KASSERT(m != NULL, ("NULL snd_mixer"));
- mtx_lock(&m->lock);
+ mtx_lock(m->lock);
ret = mixer_getrecsrc(m);
- mtx_unlock(&m->lock);
+ mtx_unlock(m->lock);
return (ret);
}
@@ -999,10 +929,6 @@
mi->modify_counter = m->modify_counter;
}
-/*
- * XXX Make sure you can guarantee concurrency safety before calling this
- * function, be it through Giant, PCM_*, etc !
- */
int
mixer_ioctl_cmd(struct cdev *i_dev, unsigned long cmd, caddr_t arg, int mode,
struct thread *td)
@@ -1041,7 +967,7 @@
if (m == NULL)
return (EBADF);
- mtx_lock(&m->lock);
+ mtx_lock(m->lock);
switch (cmd) {
case SNDCTL_DSP_GET_RECSRC_NAMES: {
oss_mixer_enuminfo *ei = (oss_mixer_enuminfo *)arg;
@@ -1096,7 +1022,7 @@
ret = mixer_set(m, j, m->mutedevs, *arg_i);
break;
}
- mtx_unlock(&m->lock);
+ mtx_unlock(m->lock);
return ((ret == 0) ? 0 : ENXIO);
}
if ((cmd & ~0xff) == MIXER_READ(0)) {
@@ -1120,11 +1046,11 @@
break;
}
*arg_i = v;
- mtx_unlock(&m->lock);
+ mtx_unlock(m->lock);
return ((v != -1) ? 0 : ENXIO);
}
done:
- mtx_unlock(&m->lock);
+ mtx_unlock(m->lock);
return (ret);
}
@@ -1257,7 +1183,6 @@
}
m = d->mixer;
- mtx_lock(&m->lock);
/*
* At this point, the following synchronization stuff
@@ -1334,8 +1259,6 @@
snprintf(mi->devnode, sizeof(mi->devnode), "/dev/mixer%d", i);
mi->legacy_device = i;
- mtx_unlock(&m->lock);
-
PCM_UNLOCK(d);
bus_topo_unlock();
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Aug 22, 2:36 PM (2 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37085091
Default Alt Text
D59074.id184640.diff (11 KB)
Attached To
Mode
D59074: sound: Use snddev_info->lock in place of snd_mixer->lock
Attached
Detach File
Event Timeline
Log In to Comment