kernel/resource.c breakage

Mikael Pettersson (mikpe@csd.uu.se)
Sun, 4 Jul 1999 02:02:51 +0200 (MET DST)


Summary: kernel/resource.c, in kernel 2.3.7 and later,
is semantically incompatible with previous versions,
and may break existing working code.

The main problem is release_region(). Previously it would
discard all information about the region. Now it _keeps_
the region description (base+extent), but gives it a magic
marker (name==NULL). The new check_region() and request_region()
will allow an existing "magic" region to be reallocated in its
entirety. Other allocations that partially interfere with a
"magic" region will not succeed.

Suppose (to make this concrete) release_region() has freed
[0x380--0x387], all of [0x370--0x38f] is free, and we're
doing a check_region(). In the old code you could allocate:
(a) [0x370--0x37f] (a disjoint region),
(b) [0x380--0x387] (an exact match),
(c) [0x381--0x386] (a subset),
(d) [0x370--0x38f] (a superset), or
(e) [0x384--0x38f] (partial overlap).
With the new code, only allocation types (a) and (b) work,
the other types will fail.

I discovered this when a device driver I use (ftape-4.03-pre2,
hacked by myself to work in 2.2.x/2.3.x kernels), stopped working
as I upgraded from kernel 2.3.6 to 2.3.9. The ftape driver did
a check_region() on [0x3f2] because it needed that I/O address
to disable the standard fdc while reusing the irq and dma for the
tape drive's controller card. The floppy driver had previously
used and then released region [0x3f0--0x3f5]. In 2.3.7 and later
kernels, the check_region() call on [0x3f2] failed because the
floppy driver's region, although now released, blocked all non-exact
reallocations.

Although this particular case was easy to work around, there are
other (hypothetical) cases that may fail too. Consider a hardware
device which initially uses I/O ports BASE+0..BASE+3, and later on
enables extended functionality via ports BASE+4 and up.
(Think about PC parallel ports.) It is entirely possible for two
different drivers to use different subsets of the total port range
for different applications. In pre-2.3.7 kernels this would work,
not so in newer kernels.

Finally, note that as of kernel 2.3.7, there's a new function
vacate_region() which implements exactly what release_region()
did in pre-2.3.7.

Since David Hinds is co-author of <linux/ioport.h> and resource.c,
I assume there's a need for the new functionality (available I/O
regions not tied to any particular driver) for pcmcia. However,
I don't think we should do this by making incompatible changes to
existing interfaces. Instead I argue that:
(a) The new release_region() ought to be renamed to some name
not present in pre-2.3.7 kernels. yield_region() perhaps?
(b) The new vacate_region() ought to be renamed to release_region(),
in order to preserve the old semantics under its existing name.
As far as I can tell, there's nothing in the kernel that actually
uses the "new and improved" semantics, so these renamings shouldn't
break anything. I'll submit a patch to Linus, if this proposal is
accepted.

Comments?

/Mikael

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