Re: trident.c vs. XMMS: 100% CPU usage

From: Brian Warner (warner@lothar.com)
Date: Mon Mar 27 2000 - 01:43:29 EST


I've got a better test case here. The following program triggers the same bug
(100% cpu, all "system"): (replace the for loop with a while(1) to see it
better):

----------------------------------------
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

char buf[4096];
int
main(void)
{
    int fd, rc, i;
    struct timeval tv;
    fd_set wset;

    fd = open("/dev/dsp", O_WRONLY);
    if (fd < 0) {
        printf("open failed\n");
        exit(0);
    }
    printf("opened\n");

    for (i=0; i < 10; i++) {
        printf("writing..\n");
        rc = write(fd, buf, 4096);
        printf(" rc=%d\n",rc);
        printf("selecting..\n");
        tv.tv_sec = 3; tv.tv_usec = 0;
        FD_ZERO(&wset);
        FD_SET(fd, &wset);
        rc = select(4, NULL, &wset, NULL, &tv);
        printf("select: %d\n", rc);
    }
    close(fd);
    exit(0);
}
----------------------------------------

If I turn on DEBUG in trident.c, then the 20ish audio syscalls made by that
program result in a few thousand lines of:
 Mar 26 22:14:51 luther kernel: trident: trident_get_dma_addr: chip reported channel: 63, cso = 0x1f74
 Mar 26 22:14:51 luther last message repeated 11 times
in my logs. That means that trident_update_ptr() is getting called repeatedly.

My suspicion is that somehow the select() is managing to make the write
process wake up too early. If I remove the select(), that code runs normally.

trident_poll() calls trident_update_ptr(), which (probably because it is
usually called from trident_interrupt()) wakes up &dmabuf->wait(), which would
wake up a writer that is sleeping until buffer space becomes available. I
can't see how that could really happen, though, because only one syscall
should be in progress at a time. The use of interruptible_sleep_on_timeout()
in trident_write() makes me a bit nervous, though, I'm wondering if there
could be a race between start_dac() and the sleep.

Anyway, that's about the extent of my debugging skills.. hope someone finds it
useful. Incidentally, kernel 2.3.42 exhibited the same behavior.

cheers,
 -Brian

-
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/



This archive was generated by hypermail 2b29 : Fri Mar 31 2000 - 21:00:19 EST