public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
From: David Woodhouse <dwmw2@infradead.org>
To: mtd@infradead.org
Cc: Philipp Rumpf <prumpf@uzix.org>
Subject: Flash chip locking
Date: Wed, 28 Jun 2000 11:36:03 +0100	[thread overview]
Message-ID: <16397.962188563@cygnus.co.uk> (raw)

OK. After some deliberation, this is the arrangement I'm about to code up 
for preventing concurrent access to flash chips. If you don't like it, 
feel free to present a better alternative.

Each chip is protected by a spinlock, which prevents it from being accessed 
concurrently by different CPUs. Lovely, simple, and even free on UP 
machines. 

Unfortunately, we have to consider the fact that this lock will also be 
obtained from a Bottom Half context, when the "has the erase finished yet?" 
timer runs. Therefore, all occurrences of spin_lock in the main code have 
to be spin_lock_bh()¹ instead of the nurmal (and almost free) spin_lock().

This means that bottom halves are disabled for the entire time that we're 
talking to the flash chip. Not good if we hold them for a long time, like 
for example the 128µs that we expect a typical write cycle to take. 

So we try to keep the latency down to a minimum. Rather than the naïve 
inner loop which looked like this:

foreach(word to write) {
	spin_lock_bh();
	writeb(WRITE_COMMAND);
	writeb(datum);
	while (!done)
		;
	spin_unlock_bh();
}

... we do something more like

foreach(word to write) {

retry:
	spin_lock_bh();
	if (!ready) {
		spin_unlock()
		udelay(a little while);
		goto retry;
	}
	writeb(WRITE_COMMAND);
	writeb(datum);
	spin_unlock_bh();
	udelay(expected time for the write we just started);
	spin_lock_bh();
	check final status, loop or whatever
	spin_unlock_bh();
}

We'll need to keep a 'state' variable in the per-chip data structure, so 
that if anything else grabs the lock while we're waiting for an operation 
to complete, it knows that there's an operation in progress and that it 
should either suspend it and do its thing before resuming the operation, 
or just go away and wait for the operation to finish.

We may add a wait queue to handle the latter case - so the write call can 
wake_up the waiting processes when it's completely finished. This will be
come more clear as I code it up.


¹ spin_lock_bh() doesn't exist in 2.2 so it's added to compatmac.h as:
#define spin_lock_bh(lock) do {start_bh_atomic();spin_lock(lock);}while(0);


--
dwmw2




To unsubscribe, send "unsubscribe mtd" to majordomo@infradead.org

             reply	other threads:[~2000-06-28 10:33 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2000-06-28 10:36 David Woodhouse [this message]
2000-06-28 20:05 ` Flash chip locking Philipp Rumpf
2000-06-29  2:11 ` Brendan Simon
2000-06-28 11:16   ` Kira Brown
2000-06-28 11:24   ` David Woodhouse
2000-06-29 13:49     ` Brendan Simon
2000-06-28 15:12   ` Richard Gooch
2000-10-13  0:16 ` Alice Hennessy
2000-10-13  0:14   ` David Woodhouse
2000-11-04 19:26   ` David Woodhouse

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=16397.962188563@cygnus.co.uk \
    --to=dwmw2@infradead.org \
    --cc=mtd@infradead.org \
    --cc=prumpf@uzix.org \
    /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