Saturday, July 17, 2010

Bug in NetBSD 1.6 - 3.1 emulation

Was going to write that I couldn't imagine what did the NetBSD guys smoke during 5 years between the versions 1.6 and 3.1 inclusively. The NCR 53c9x SCSI chip (known as "esp" in SPARC and PPC machines) was not so uncommon back then. How could they introduce an instability and didn't notice it ?!?

The code from NetBSD 1.5.3:

NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0, &dmasize);
//...
NCRCMD(sc, NCRCMD_SELATN | NCRCMD_DMA);
NCRDMA_GO(sc);

The code from NetBSD 1.6-3.1:

NCRCMD(sc, NCRCMD_SELATN | NCRCMD_DMA);
NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0, &dmasize);
NCRDMA_GO(sc);

The code from NetBSD 4:

NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0, &dmasize);
//...
NCRCMD(sc, NCRCMD_SELATN | NCRCMD_DMA);
NCRDMA_GO(sc);

See the difference? In the versions 1.6-3.1 the command is executed before the DMA is set up, so the SCSI controller may not get the command using DMA.

And then I googled for the expected bug reports and found none. Why could it work on the real hardware? Maybe some latency: if the latency of a SCSI controller was larger than a DMA controller, it might work? Maybe concurrency: if some other driver (for instance Ethernet) prepared DMA for itself, the SCSI driver could steal it? Maybe DMA didn't work for these versions at all and after the first attempt they switched to the PIO mode.

2 comments:

4DA said...

может быть, стоит написать в рассылку netbsd tech-kern?

случай действительно интересный...

atar said...

Уже писал в список рассылки NetBSD (без реакции), но и проблему уже сам расковырял.

Это не баг в NetBSD. В документации на контроллер скази сказано не очень чётко, в каком порядке надо программировать dma и esp. Разработчики qemu решили, что dma сконфиругировано, но пересылка в обе стороны выполняется контроллером esp.

В результате имеем практически полностью неправильную реализацию select with(out) attention. Дело усложняется тем, что контроллер esp используется при эмуляции mips и ppc, и в каждом из случаев дма предположительно по разному работает (во всяком случае, по разному реализовано в qemu).

В результате мы с маитенером так и не пришли к общему мнению, как исправлять.

Пока что отложил до лучших времён - если возникнет проблема в какой-то из нужных мне ос - вернусь к этому багу.