Re: Linux kernel 2.6.x Raw device support
Joerg Schilling <email@example.com> wrote:
> Dave Platt <firstname.lastname@example.org> wrote:
> > > I believe that the reason for not implementing raw devices on Linux was the fact
> > > that Linux was designed for x86 and the way Linux did implement DMA to devices
> > > would have made a raw device slower than a buffered device.
> > I believe that your belief is entirely wrong.
> So please proove...
I believe I already have! As I pointed out, I successfully built a
system, based on a 2.4 kernel, which uses the /dev/raw/* API
and does DMA directly to/from large buffers of user memory, and
which greatly outperforms the equivalent code running against the
The DMA directly to user memory was very efficient. The kernel
buffer pool wasn't used, and there was no kernel-based memcopying
of data between user memory and the kernel buffer pool.
It took about two days to develop this, using a stock 2.4 kernel
and standard devices and device drivers. The resulting "Super Duper"
device was put into commercial service at a large disk-duplicating
house. It significantly outperformed the commercial IDE disk
duplicators of that era, and was a lot less expensive to
acquire (we built 'em using low-end off-the-shelf PC systems
from Fry's, and off-the-shelf 2-port PCI-bus UDMA controllers).
As I said - it works, and the throughput turned out to be limited
by the PCI-bus-to-memory bandwidth, not by the CPU.
> > I've used the (2.2 and 2.4) /dev/raw/* version of Linux raw devices
> > for several years now, to create a high-speed disk duplication system.
> > It runs on commodity X86 hardware, using off-the-shelf PCI-bus UDMA
> > IDE controllers.
> I've never seen /dev/raw/* on a Linux-2.4 system.
> I did however check the linux kernel-2.2 sources because I was trying
> to implement a better SCSI Generic driver that time. If the Linux
> kernel has been able to do user mode DMA, then there was no need to
> allocate a special DMA buffer inside the kernel and to use copyout
> (or it's Linux equivalent) later to move the data to userland.
My recollection was that the Linux implementation of /dev/raw/* was
either a late 2.2, or early 2.3/2.4 sort of thing. I used a fairly
early 2.4 kernel to build the first version of the "Super Duper".
It may well have been that this code was not in the kernel version
you studied. Your belief that Linux is not designed to do this
*was* true in the past, I know.
It's not true for the current kernels, though. The feature is
present, available, and works very efficiently.
It does have certain limitations, granted - you have to be careful
about your buffer alignments, and you have to explicitly ask for it
(via binding a /dev/raw/* device in 2.4, and now via O_DIRECT in
2.6). It doesn't come "for free" - normal, standard disk I/O
still goes through the kernel buffer pool.