On Tuesday May 30, nickpiggin@xxxxxxxxxxxx wrote:
Nick Piggin wrote:
For workloads where plugging helps (ie. lots of smaller, contiguous
requests going into the IO layer), the request pattern should be
pretty good without plugging these days, due to multiple page
readahead and writeback.
Can I please put in a vote for not thinking that every device is disk
drive?
I find plugging fairly important for raid5, particularly for write.
The more whole-stripe writes I can get, the better throughput I get.
So I tend to keep a raid5 array plugged while any requests are
arriving, and interpret 'plugged' to mean that incomplete stripes
don't get processed while full stripes (needing no pre-reading) do get
processed.
The only way "large requests" are going to replace plugging is they
are perfectly aligned, which I don't expect to ever see.
As for your original problem.... I wonder if PG_locked is protecting
too much? It protects against IO and it also protects against ->mapping
changes. So if you want to ensure that ->mapping won't change, you
need to wait for any pending read request to finish, which seems a bit
dumb.
Maybe we need a new bit: PG_maplocked. You are only allowed to change
->mapping or ->index of you hold PG_locked and PG_maplocked, you are
not allowed to wait for PG_locked while holding PG_maplocked, and
you can read ->mapping or ->index while PG_locked or PG_maplocked are
held.
Think of PG_locked like a mutex and PG_maplocked like a spinlock (and
probably use bit_spinlock to get it).
Then set_page_dirty_lock would use PG_maplocked to get access to
->mapping, and then hold a reference on the address_space while
calling into balance_dirty_pages ... I wonder how you hold a reference
on an address space...
There are presumably few pieces of code that change ->mapping. Once
they all take PG_maplocked as well as PG_locked, you can start freeing
up other code to take PG_maplocked instead of PG_locked....
Does that make sense at all? Do we have any spare page bits?