change sb_writers to use percpu_rw_semaphore
authorOleg Nesterov <oleg@redhat.com>
Tue, 11 Aug 2015 15:05:04 +0000 (17:05 +0200)
committerOleg Nesterov <oleg@redhat.com>
Sat, 15 Aug 2015 11:52:13 +0000 (13:52 +0200)
commit8129ed29644bf56ed17ec1bbbeed5c568b43d6a0
tree14a01f7077300477f7f1f7e7c3ad1b9b6589dd32
parent853b39a7c82826b8413048feec7bf08e98ce7a84
change sb_writers to use percpu_rw_semaphore

We can remove everything from struct sb_writers except frozen
and add the array of percpu_rw_semaphore's instead.

This patch doesn't remove sb_writers->wait_unfrozen yet, we keep
it for get_super_thawed(). We will probably remove it later.

This change tries to address the following problems:

- Firstly, __sb_start_write() looks simply buggy. It does
  __sb_end_write() if it sees ->frozen, but if it migrates
  to another CPU before percpu_counter_dec(), sb_wait_write()
  can wrongly succeed if there is another task which holds
  the same "semaphore": sb_wait_write() can miss the result
  of the previous percpu_counter_inc() but see the result
  of this percpu_counter_dec().

- As Dave Hansen reports, it is suboptimal. The trivial
  microbenchmark that writes to a tmpfs file in a loop runs
  12% faster if we change this code to rely on RCU and kill
  the memory barriers.

- This code doesn't look simple. It would be better to rely
  on the generic locking code.

  According to Dave, this change adds the same performance
  improvement.

Note: with this change both freeze_super() and thaw_super() will do
synchronize_sched_expedited() 3 times. This is just ugly. But:

- This will be "fixed" by the rcu_sync changes we are going
  to merge. After that freeze_super()->percpu_down_write()
  will use synchronize_sched(), and thaw_super() won't use
  synchronize() at all.

  This doesn't need any changes in fs/super.c.

- Once we merge rcu_sync changes, we can also change super.c
  so that all wb_write->rw_sem's will share the single ->rss
  in struct sb_writes, then freeze_super() will need only one
  synchronize_sched().

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Jan Kara <jack@suse.com>
fs/super.c
include/linux/fs.h