linux/drivers
Weijie Yang d2d5e762c8 zram: replace global tb_lock with fine grain lock
Currently, we use a rwlock tb_lock to protect concurrent access to the
whole zram meta table.  However, according to the actual access model,
there is only a small chance for upper user to access the same
table[index], so the current lock granularity is too big.

The idea of optimization is to change the lock granularity from whole
meta table to per table entry (table -> table[index]), so that we can
protect concurrent access to the same table[index], meanwhile allow the
maximum concurrency.

With this in mind, several kinds of locks which could be used as a
per-entry lock were tested and compared:

Test environment:
x86-64 Intel Core2 Q8400, system memory 4GB, Ubuntu 12.04,
kernel v3.15.0-rc3 as base, zram with 4 max_comp_streams LZO.

iozone test:
iozone -t 4 -R -r 16K -s 200M -I +Z
(1GB zram with ext4 filesystem, take the average of 10 tests, KB/s)

      Test       base      CAS    spinlock    rwlock   bit_spinlock
-------------------------------------------------------------------
 Initial write  1381094   1425435   1422860   1423075   1421521
       Rewrite  1529479   1641199   1668762   1672855   1654910
          Read  8468009  11324979  11305569  11117273  10997202
       Re-read  8467476  11260914  11248059  11145336  10906486
  Reverse Read  6821393   8106334   8282174   8279195   8109186
   Stride read  7191093   8994306   9153982   8961224   9004434
   Random read  7156353   8957932   9167098   8980465   8940476
Mixed workload  4172747   5680814   5927825   5489578   5972253
  Random write  1483044   1605588   1594329   1600453   1596010
        Pwrite  1276644   1303108   1311612   1314228   1300960
         Pread  4324337   4632869   4618386   4457870   4500166

To enhance the possibility of access the same table[index] concurrently,
set zram a small disksize(10MB) and let threads run with large loop
count.

fio test:
fio --bs=32k --randrepeat=1 --randseed=100 --refill_buffers
--scramble_buffers=1 --direct=1 --loops=3000 --numjobs=4
--filename=/dev/zram0 --name=seq-write --rw=write --stonewall
--name=seq-read --rw=read --stonewall --name=seq-readwrite
--rw=rw --stonewall --name=rand-readwrite --rw=randrw --stonewall
(10MB zram raw block device, take the average of 10 tests, KB/s)

    Test     base     CAS    spinlock    rwlock  bit_spinlock
-------------------------------------------------------------
seq-write   933789   999357   1003298    995961   1001958
 seq-read  5634130  6577930   6380861   6243912   6230006
   seq-rw  1405687  1638117   1640256   1633903   1634459
  rand-rw  1386119  1614664   1617211   1609267   1612471

All the optimization methods show a higher performance than the base,
however, it is hard to say which method is the most appropriate.

On the other hand, zram is mostly used on small embedded system, so we
don't want to increase any memory footprint.

This patch pick the bit_spinlock method, pack object size and page_flag
into an unsigned long table.value, so as to not increase any memory
overhead on both 32-bit and 64-bit system.

On the third hand, even though different kinds of locks have different
performances, we can ignore this difference, because: if zram is used as
zram swapfile, the swap subsystem can prevent concurrent access to the
same swapslot; if zram is used as zram-blk for set up filesystem on it,
the upper filesystem and the page cache also prevent concurrent access
of the same block mostly.  So we can ignore the different performances
among locks.

Acked-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Reviewed-by: Davidlohr Bueso <davidlohr@hp.com>
Signed-off-by: Weijie Yang <weijie.yang@samsung.com>
Signed-off-by: Minchan Kim <minchan@kernel.org>
Cc: Jerome Marchand <jmarchan@redhat.com>
Cc: Nitin Gupta <ngupta@vflare.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2014-08-06 18:01:23 -07:00
..
accessibility
acpi APEI is currently implemented so that it depends on x86 hardware. 2014-07-30 10:48:00 -07:00
amba
ata ata: libahci: Silence compiler warning on 64-bit 2014-08-01 11:18:53 -04:00
atm drivers: atm: fix %d confusingly prefixed with 0x in format strings 2014-08-05 13:04:32 -07:00
auxdisplay
base mm: export NR_SHMEM via sysinfo(2) / si_meminfo() interfaces 2014-08-06 18:01:19 -07:00
bcma bcma: use NS prefix for names of Northstar specific cores 2014-07-31 13:45:32 -04:00
block zram: replace global tb_lock with fine grain lock 2014-08-06 18:01:23 -07:00
bluetooth Bluetooth: Fix crash in the Marvell driver initialization codepath 2014-07-31 01:07:28 +02:00
bus
cdrom
char Cleanups and bug fixes to /dev/random, add a new getrandom(2) system 2014-08-06 08:16:24 -07:00
clk The clock framework changes for 3.17 are mostly additions of new clock 2014-08-04 11:44:20 -07:00
clocksource Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2014-08-05 17:46:42 -07:00
connector connector: Use ktime_get_ns() 2014-07-23 10:18:07 -07:00
cpufreq cpufreq: move policy kobj to policy->cpu at resume 2014-07-17 14:23:22 +02:00
cpuidle
crypto Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6 2014-08-04 09:52:51 -07:00
dca
devfreq
dio
dma dma: Fix MIC X100 DMA Driver Kconfig option 2014-07-16 13:47:54 -07:00
dma-buf reservation: add suppport for read-only access using rcu 2014-07-08 13:41:08 -07:00
edac Merge branch 'x86-ras-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2014-08-04 17:21:59 -07:00
eisa
extcon extcon: sm5502: Change internal hardware switch according to cable type 2014-07-23 10:22:35 +09:00
firewire Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2014-08-06 09:38:14 -07:00
firmware drivers/firmware/memmap.c: don't allocate firmware_map_entry of same memory range 2014-08-06 18:01:20 -07:00
fmc
gpio Pin control fixes for v3.16: 2014-07-23 17:42:37 -07:00
gpu Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2014-08-05 17:46:42 -07:00
hid [media] rc-core: remove protocol arrays 2014-07-25 19:10:43 -03:00
hsi net: set name_assign_type in alloc_netdev() 2014-07-15 16:12:48 -07:00
hv Char / Misc driver patches for 3.17-rc1 2014-08-04 17:32:24 -07:00
hwmon Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2014-08-05 17:46:42 -07:00
hwspinlock
i2c The clock framework changes for 3.17 are mostly additions of new clock 2014-08-04 11:44:20 -07:00
ide ide: use module_platform_driver() 2014-08-05 21:16:46 -07:00
idle
iio Staging driver patches for 3.17-rc1 2014-08-04 18:36:12 -07:00
infiniband mlx5: Adjust events to use unsigned long param instead of void * 2014-07-30 14:00:06 -07:00
input Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next 2014-08-06 09:41:23 -07:00
iommu Merge branches 'x86/vt-d', 'x86/amd', 'arm/omap', 'ppc/pamu', 'arm/smmu', 'arm/exynos' and 'core' into next 2014-07-31 20:29:02 +02:00
ipack ipack: Replace DEFINE_PCI_DEVICE_TABLE macro use 2014-07-18 16:50:55 -07:00
irqchip Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2014-08-05 17:38:45 -07:00
isdn net: filter: split 'struct sk_filter' into socket and bpf parts 2014-08-02 15:03:58 -07:00
leds
lguest mm/vmalloc.c: clean up map_vm_area third argument 2014-08-06 18:01:19 -07:00
macintosh
mailbox
mcb
md Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2014-08-04 16:23:30 -07:00
media Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2014-08-06 09:38:14 -07:00
memory
memstick
message
mfd Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2014-08-05 17:46:42 -07:00
misc Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2014-08-06 09:38:14 -07:00
mmc
mtd Two UBI fastmap-related fixes for v3.16: 2014-07-18 06:23:34 -10:00
net Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2014-08-06 09:38:14 -07:00
nfc NFC: st21nfca: Adding P2P support to st21nfca in Initiator & Target mode 2014-07-23 01:14:41 +02:00
ntb
nubus
of Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2014-08-05 17:46:42 -07:00
oprofile
parisc
parport parport: fix menu breakage 2014-07-25 18:00:23 -07:00
pci Char / Misc driver patches for 3.17-rc1 2014-08-04 17:32:24 -07:00
pcmcia pcmcia: remove DEFINE_PCI_DEVICE_TABLE usage 2014-07-18 16:58:07 -07:00
phy phy: miphy365x: Represent each PHY channel as a DT subnode 2014-07-22 12:46:43 +05:30
pinctrl pinctrl: st: Fix irqmux handler 2014-07-15 20:55:15 +02:00
platform
pnp ACPI / PNP: Fix acpi_pnp_match() 2014-07-30 00:23:09 +02:00
power
powercap
pps
ps3
ptp
pwm
rapidio rapidio/tsi721_dma: fix failure to obtain transaction descriptor 2014-07-30 17:16:13 -07:00
ras
regulator Merge remote-tracking branches 'regulator/topic/tps65217', 'regulator/topic/tps65218', 'regulator/topic/tps6586x' and 'regulator/topic/twl' into regulator-next 2014-08-05 18:29:30 +01:00
remoteproc
reset
rpmsg
rtc
s390 Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2014-07-22 00:44:59 -07:00
sbus Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc 2014-08-05 18:57:18 -07:00
scsi Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2014-08-06 09:38:14 -07:00
sfi
sh
sn
soc
spi spi: Updates for v3.17 2014-08-05 16:18:13 -07:00
spmi spmi: Remove duplicate inclusion of module.h 2014-07-10 15:22:13 -07:00
ssb ssb: extract power info from SPROM revs 4 and 5 2014-07-18 13:45:24 -04:00
staging mm/vmalloc.c: clean up map_vm_area third argument 2014-08-06 18:01:19 -07:00
target Merge branch 'for-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu 2014-08-04 10:09:27 -07:00
tc
thermal
thunderbolt thunderbolt: Use kcalloc 2014-07-13 13:16:50 -07:00
tty mm, oom: ensure memoryless node zonelist always includes zones 2014-08-06 18:01:21 -07:00
uio Merge 3.16-rc5 into char-misc-next 2014-07-13 15:26:47 -07:00
usb Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2014-08-06 09:38:14 -07:00
uwb uwb/whci: use correct structure type name in sizeof 2014-08-01 15:48:08 -07:00
vfio
vhost
video PCI changes for the v3.17 merge window: 2014-08-04 09:29:37 -07:00
virt
virtio
vlynq
vme VME: remove duplicate CA91CX42_DCTL_VDW_M define 2014-07-09 16:33:42 -07:00
w1
watchdog
xen Merge branch 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2014-08-04 17:13:50 -07:00
zorro zorro: Use ARRAY_SIZE 2014-07-11 10:38:02 +02:00
Kconfig Char / Misc driver patches for 3.17-rc1 2014-08-04 17:32:24 -07:00
Makefile Driver core patches for 3.17-rc1 2014-08-04 18:34:04 -07:00