[patch] bttv SMP races 2.3.18ac8

Andrea Arcangeli (andrea@suse.de)
Thu, 23 Sep 1999 17:27:04 +0200 (CEST)


I found some SMP race in the bttv sem locking. Also if vmalloc fails to
allocate the kernel grab-video-framebuffer memory, then IMHO the right
retval for userspace is -ENOMEM and not -EINVAL. I also moved the
audio(UNMUTE) in the successfully path to semplify the fail path
(previously I think the audio could remain alive if the vmalloc failed).

--- 2.3.18ac8/drivers/char/bttv.c Wed Sep 22 19:22:36 1999
+++ /tmp/bttv.c Thu Sep 23 17:20:31 1999
@@ -1558,21 +1558,18 @@
static int bttv_open(struct video_device *dev, int flags)
{
struct bttv *btv = (struct bttv *)dev;
- int i;
+ int i, ret;

- if (btv->user)
- return -EBUSY;
-
+ ret = -EBUSY;
down(&btv->lock);
- audio(btv, AUDIO_UNMUTE);
- btv->fbuffer=NULL;
- if (!btv->fbuffer)
- btv->fbuffer=(unsigned char *) rvmalloc(2*BTTV_MAX_FBUF);
+ if (btv->user)
+ goto out_unlock;
+
+ btv->fbuffer= (unsigned char *) rvmalloc(2*BTTV_MAX_FBUF);
+ ret = -ENOMEM;
if (!btv->fbuffer)
- {
- up(&btv->lock);
- return -EINVAL;
- }
+ goto out_unlock;
+ audio(btv, AUDIO_UNMUTE);
btv->grabbing = 0;
btv->grab = 0;
btv->lastgrab = 0;
@@ -1583,6 +1580,10 @@
up(&btv->lock);
MOD_INC_USE_COUNT;
return 0;
+
+ out_unlock:
+ up(&btv->lock);
+ return ret;
}

static void bttv_close(struct video_device *dev)
@@ -2463,11 +2464,11 @@
{
struct bttv *btv = (struct bttv *)(dev-1);

+ down(&btv->lock);
if (btv->user)
- return -EBUSY;
+ goto busy_unlock;
btv->user++;

- down(&btv->lock);
set_freq(btv,400*16);
btv->radio = 1;
bt848_muxsel(btv,0);
@@ -2476,15 +2477,21 @@

MOD_INC_USE_COUNT;
return 0;
+
+ busy_unlock:
+ up(&btv->lock);
+ return -EBUSY;
}

static void radio_close(struct video_device *dev)
{
struct bttv *btv=(struct bttv *)(dev-1);

+ down(&btv->lock);
btv->user--;
btv->radio = 0;
/*audio(btv, AUDIO_MUTE);*/
+ up(&btv->lock);
MOD_DEC_USE_COUNT;
}


Andrea

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/