[Cbe-oss-dev] spufs: kernel hangs by polling 'mfc' w/o proxy DMA request

Kazunori Asayama asayama at sm.sony.co.jp
Tue Sep 18 13:21:45 EST 2007


Arnd Bergmann <arnd at arndb.de> wrote:
> On Friday 07 September 2007, Kazunori Asayama wrote:
> > I found that the kernel hangs if programs poll 'mfc' node of SPUFS
> > without proxy DMA requests. The reason why this problem occurs is
> > that:
> > 
> >   - If spufs_mfc_poll, which is the 'poll' operator of 'mfc', is
> >     called without proxy DMA requests, spufs_mfc_poll issues a proxy
> >     tag group query with query mask = 0 and query type = 2 (all):
> > 
> > 	ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2);
> > 
> >     The processor immediately raises a 'tag-group completion
> >     interrupt' corresponding to this query, because there is no
> >     outstanding proxy DMA at all.
> > 
> >   - The spufs_mfc_poll never (regardless of other conditions) returns
> >     POLLIN event when tagwait (a set of issued proxy DMA) is zero:
> > 
> > 	if (tagstatus & ctx->tagwait)
> > 		mask |= POLLIN | POLLRDNORM;
> > 
> >   - As a result of the above, spufs_mfc_poll endlessly issues proxy
> >     tag group queries with query mask = 0 and query type = 2, if once
> >     spufs_mfc_poll is called without proxy DMA request.
> 
> Oh, you mean it gets into a busy-loop? That should really not
> happen.

Yes, right.

> 
> I suppose we should immediately return from the loop when a program
> accidentally calls poll() without having entered any requests into
> the queue first, like
> 
> 	if (!ctx->tagwait)
> 		mask |= POLLERR;
> 
> and have the read function on the file return -EINVAL.

There is a practical problem with such a behavior when waiting for
events, especially by using epoll_wait, in event loops.

In general, a typical sequence to process events by epoll in an event
loop is:

  /* register events */
  epoll_ctl(epfd, EPOLL_CTL_ADD, fd_mfc, &event_mfc);
  epoll_ctl(epfd, EPOLL_CTL_ADD, fd_ibox, &event_ibox);
    ...

  while (1) {
    /* wait for next events */
    epoll_wait(epfd, ...);

    /* process events */
  }

  /* unregister events */
  epoll_ctl(epfd, EPOLL_CTL_DEL, fd_mfc, NULL);
  epoll_ctl(epfd, EPOLL_CTL_DEL, fd_ibox, NULL);
    ...

But if the spufs_mfc_poll returns an error immediately when no proxy
DMA command is issued, we need to modify epoll file descriptor in the
event loop frequently, when a new proxy DMA command is issued and when
all outstanding proxy DMAs are completed, as following:

  while (1) {
    if (a new proxy DMA command is issued) {
      epoll_ctl(epfd, EPOLL_CTL_ADD, fd_mfc, &event_mfc);
    }

    epoll_wait(epfd, ...);

    if (all proxy DMAs are completed) {
      epoll_ctl(epfd, EPOLL_CTL_DEL, fd_mfc, NULL);
    }
  }

So I propose waiting until new data becomes available on "mfc", even
if the poll is called when no proxy DMA command is issued.

--
(ASAYAMA Kazunori
  (asayama at sm.sony.co.jp))
t



More information about the cbe-oss-dev mailing list