Subject: kern/34659: audio(4) can cause system lock-up
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Andreas Gustafsson <gson@gson.org>
List: netbsd-bugs
Date: 09/29/2006 07:55:00
>Number:         34659
>Category:       kern
>Synopsis:       audio(4) can cause system lock-up
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Sep 29 07:55:00 +0000 2006
>Originator:     Andreas Gustafsson
>Release:        NetBSD 3.99.24
>Organization:
>Environment:
System: NetBSD guava.gson.org 3.99.24 NetBSD 3.99.24 (GENERIC) #0: Fri Aug 4 13:14:16 EEST 2006 root@guru.araneus.fi:/usr/build/1005/obj/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:

When running the following test program on a machine equipped with an
Ensoniq AudioPCI sound card, the operating system locks up within a
few seconds.  Systems with other full duplex capable sound cards may
or may not be affected.

A DDB stack trace obtained from a system in the locked-up state
indicates that the kernel is executing in audio_read().

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>

#include <sys/audioio.h>
#include <sys/ioctl.h>

int gen() {
	return 0;
}

int main(int argc, char **argv)
{
	char buf[48000 * 2 * 2];
	char rbuf[128];	
	int i;
	int fd;
	int r;
	audio_info_t info;

	fd = open("/dev/sound0", O_RDWR);

	/* Set to 48 kHz, mono, 16 bit */
	AUDIO_INITINFO(&info);
	info.play.sample_rate = 48000;
	info.play.channels = 1;
	info.play.precision = 16;	
	info.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
	r = ioctl(fd, AUDIO_SETINFO, &info);
	if (r < 0) {
		fprintf(stderr, "ioctl AUDIO_SETINFO: %s\n", strerror(errno));
		exit(1);
	}

	/* Set nonblocking mode */
	r = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
	if (r < 0) {
		fprintf(stderr, "fcntl O_NONBLOCK: %s\n", strerror(errno));
		exit(1);
	}

	for (;;) {
		for (i = 0; i < sizeof buf; i++)
			buf[i] = gen();
		write(fd, buf, sizeof buf);
		read(fd, rbuf, sizeof rbuf);		
	}
}

>How-To-Repeat:

See above.

>Fix:

None provided.