mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Alain Knaff <Alain.Knaff@hitchhiker.org.lu>
To: Alexander Viro <viro@math.psu.edu>
Cc: Linus Torvalds <torvalds@transmeta.com>,
	Richard Gooch <rgooch@ras.ucalgary.ca>,
	linux-kernel@vger.kernel.org
Subject: Re: Poor floppy performance in kernel 2.4.10
Date: Sat, 27 Oct 2001 19:12:41 +0200	[thread overview]
Message-ID: <200110271712.f9RHCgf02886@hitchhiker.org.lu> (raw)
In-Reply-To: Your message of "Sat, 27 Oct 2001 11:15:45 EDT." <Pine.GSO.4.21.0110271103560.21545-100000@weyl.math.psu.edu>

>
>
>On Sat, 27 Oct 2001, Alain Knaff wrote:
>
>> Appended to this mail is a patch meant to fix the "non-cached floppy"
>> problem.
>
>a) you _still_ need to stop all pending IO (readaheads in progress)
>before final ->release()

Ok. Didn't know about that. Maybe we should add a variant of
invalidate_bdev which stops IO in progress, but which wouldn't throw
away data that has already been read? This same variant could also
make sure that no dirty buffers were around, as a sanity check.

>b) at which point do you flush the cache?  It definitely shouldn't
>survive rmmod.

In the case of the floppy driver, the following would happen: after
rmmod, followed by insmod, the floppy driver would assume the disk has
been changed an throw away the cache (by returning 1 from
check_media_change). This is actually a side-effect of the way how the
physical DCL status is cleared: after an insmod, the floppy driver has
no way of knowing whether DCL was set at some point in the past, but
then cleared by another driver (i.e. ftape), so it errs on the safe
side, and assumes the disk has been changed.

Other block device drivers may behave differently of course...

>  And no, unregister_blkdev() is not a solution, courtesy
>of devfs with its insane devfs=only option.


Do you mean this:

int devfs_unregister_blkdev (unsigned int major, const char *name)
{
    if (boot_options & OPTION_ONLY) return 0;
    return unregister_blkdev (major, name);
}   /*  End Function devfs_unregister_blkdev  */

It seems to me that the root of the problem here is that the normal
major->device mapping is no longer the only way to "find" a device.

Cursory examination of floppy.c (as an example of a block device
driver) showed that bdops are also registered using devfs_register and
register_disk (what's THAT for?!? Floppies don't have partitions...)

Apparently, devfs_register allows a direct mapping from the device's
name to its driver, without going through its major/minor number.

Thus, a possible solution would be to equip all possible paths leading
to the driver's block_device_operations with correct "teardown"
function. Thus, not only unregister_blkdev would dump the cache, but
also devfs_unregister (maybe near the place in unregister() where
de->u.fcb.ops = NULL is done?). Best make this call generic, such as
free_bd_ops(handle), so that other unregister actions could easily be
tucked on top of it later on, should the need arise.

All this begs of course the following question: what kind of
idnetifier does the buffer cache code actually use to refer to the
block device, if there is no longer a major?

Is a pointer to some kind of structure used as the identifier? If so,
what structure is this? The device driver's block_device_operations
structure? No, won't work, because there may be minors. Or is it
something which is allocated on the fly when the device is opened? If
it is indeed the latter, I think I understand why the cache is gone
after re-opening the device: maybe it just gets a different handle
(mapping)? The cache may still be there, but the VFS would no longer
"find" it because the identifier of the device has changed. Should we
maybe use a _combination_ of pointer to block_device_operations and
minor number as the identifier for the device? That should stay valid
all the time while the module is loaded.

>There is a related problem which is much nastier than short-living caches:
>code that does bdev->bd_op = <stuff from devfs>;  blkdev_get(bdev, ...);
>Think what happens if rmmod comes while blkdev_get() sleeps ob ->bd_sem.
>Notice that it had been there since the moment when devfs went into the
>tree.  Sigh...

I'm not sure I understand the full extent of the problem, but at a
quick glance, it seems to be that the only operation exposed would be
blkdev_open, as all other operations do need an open handle, which
would prevent rmmod because module usage count would not be zero (at
least, if the module is correctly implemented...).

We would thus need to protect bd_op between the time it has been
fetched via get_blkfops, and bd_op->open. After bd_op->open, we would
be safe because of module usage count.

We could either use bdev->bd_sem (awkward, as many drivers implement
multiple bdev's), or a new per-major device lock to protect that
section.

unregister_blkdev would need to acquire the same lock while zero-ing
blkdevs[major].bdops.

Right now, block_dev.c's do_open already holds the kernel lock, so
wouldn't it be enough to also lock_kernel() in unregister_blkdev ?

A symetric situation might occur if a bd_op was called after
bd_op->release. But as far as I could see, this is not the case. Even
my own patch added the call to bd_op->can_trust_media_change _before_
the bd_op->release.

Ok, so the above only describes the solution where a device is
accessed via its major. To transpose this to devfs' direct
name-to-device mappings, a similar lock would need to be held between
the time the bd_op pointer is established, and the time it is
opened. But this may not practical, because too many software
components would be involved in that critical section. So maybe
do_open could "revalidate" the bd_op pointer (i.e. somehow check
whether the block device driver has not yet been unregistered in the
meantime) just before using it, and have the critical section only
enclose the revalidate and bd_op->open operation.

Something like the following (do_open):

	down(&bdev->bd_sem);
	lock_kernel();
+       if(bdev->bd_op && !devfs_is_bdop_still_valid(inode,bdev)) {
+               unlock_kernel();
+               up(&bdev->bd_sem);
+               return -ENODEV;
+       }
	if (!bdev->bd_op)
		bdev->bd_op = get_blkfops(MAJOR(dev));
	if (bdev->bd_op) {
		ret = 0;
		if (bdev->bd_op->open)
			ret = bdev->bd_op->open(inode, file);
		if (!ret) {
			bdev->bd_openers++;
			bdev->bd_inode->i_size = blkdev_size(dev);
			bdev->bd_inode->i_blkbits = blksize_bits(block_size(dev));
		} else if (!bdev->bd_openers)
			bdev->bd_op = NULL;
	}
	unlock_kernel();
	up(&bdev->bd_sem);


Regards,

Alain

  reply	other threads:[~2001-10-27 17:12 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-10-27 15:00 Alain Knaff
2001-10-27 15:15 ` Alexander Viro
2001-10-27 17:12   ` Alain Knaff [this message]
2001-10-27 17:42     ` Alexander Viro
2001-10-27 18:00       ` Alain Knaff
2001-10-27 18:13         ` Alexander Viro
2001-10-27 18:26         ` Alexander Viro
2001-10-27 19:02           ` more devfs fun Alexander Viro
2001-10-27 19:16             ` Alexander Viro
2001-10-27 19:50               ` more devfs fun (Piled Higher and Deeper) Alexander Viro
2001-10-27 20:06                 ` Alexander Viro
2001-10-27 21:09                   ` Ryan Cumming
2001-10-27 21:22                     ` Alexander Viro
2001-10-28  1:00                     ` Rik van Riel
2001-10-28  8:45                     ` Richard Gooch
2001-10-28  9:54                       ` Alexander Viro
2001-10-28 12:27                       ` Roman Zippel
2001-10-28 13:16                         ` Alexander Viro
2001-10-28 22:31                       ` Richard Gooch
2001-10-28 23:11                         ` Alexander Viro
2001-10-27 21:01                 ` Alexander Viro
2001-11-06  6:35                 ` Richard Gooch
2001-11-06  7:10                   ` Alexander Viro
2001-11-06  7:14                   ` Richard Gooch
2001-11-06  7:17                     ` Alexander Viro
2001-11-06 20:14                     ` Richard Gooch
2001-10-28 10:06               ` Lorenzo Allegrucci
2001-11-06  5:21               ` Richard Gooch
2001-11-06  5:17             ` more devfs fun Richard Gooch
2001-11-06  5:06           ` Richard Gooch
2001-11-06  7:01         ` Poor floppy performance in kernel 2.4.10 Richard Gooch
2001-11-06  7:03           ` Alexander Viro
2001-12-09  5:38           ` Devfs races with block devices Richard Gooch
2001-11-06  7:19         ` Poor floppy performance in kernel 2.4.10 Richard Gooch
2001-11-06  7:22           ` Alexander Viro
2001-10-27 19:13       ` Alain Knaff
2001-10-27 19:19         ` Alexander Viro
2001-10-27 19:26           ` Alain Knaff
2001-10-28 20:40           ` Alain Knaff
2001-10-28 20:57             ` Peter T. Breuer
2001-10-29  5:38               ` Alain Knaff
2001-10-29  6:07                 ` Alexander Viro
2001-10-29  6:34                   ` Alain Knaff
2001-10-28 21:42             ` Alexander Viro
  -- strict thread matches above, loose matches on Subject: below --
2001-10-21 11:36 Alain Knaff
2001-10-22  9:59 ` Andrea Arcangeli
2001-10-22 10:06   ` Alexander Viro
2001-10-22 14:07 ` Nick LeRoy
2001-10-22 18:28 ` bill davidsen
2001-10-19 16:58 Manfred Spraul
2001-10-17  7:36 Kamil Iskra
2001-10-17 20:45 ` Steve Kieu
2001-10-18 10:11   ` Kamil Iskra
2001-10-18 15:28     ` Andreas Dilger
2001-10-18 15:42       ` Kamil Iskra
2001-10-18 16:17         ` Ville Herva
2001-10-18 16:30           ` Nick LeRoy
2001-10-18 19:57             ` bill davidsen
2001-10-18 20:47               ` Nick LeRoy
2001-10-18 20:05             ` bill davidsen
2001-10-18 20:15               ` Alexander Viro
2001-10-18 16:18       ` Alexander Viro
2001-10-18 17:44         ` Andrea Arcangeli
2001-10-19  7:50           ` Giuliano Pochini
2001-10-19 13:46             ` Andrea Arcangeli
2001-10-19 15:57             ` Linus Torvalds
2001-10-20  4:20               ` Rob Landley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200110271712.f9RHCgf02886@hitchhiker.org.lu \
    --to=alain.knaff@hitchhiker.org.lu \
    --cc=alain@linux.lu \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rgooch@ras.ucalgary.ca \
    --cc=torvalds@transmeta.com \
    --cc=viro@math.psu.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®