Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1426199 > unrolled thread

[PATCH 0/5] Implement bitlock map allocator

Started byByungchul Park <byungchul.park@lge.com>
First post2016-06-20 07:20 +0200
Last post2016-06-20 07:20 +0200
Articles 3 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/5] Implement bitlock map allocator Byungchul Park <byungchul.park@lge.com> - 2016-06-20 07:20 +0200
    [PATCH 4/5] fs/buffer.c: Remove trailing white space Byungchul Park <byungchul.park@lge.com> - 2016-06-20 07:20 +0200
    [PATCH 2/5] lockdep: Apply bitlock to bit_spin_lock Byungchul Park <byungchul.park@lge.com> - 2016-06-20 07:20 +0200

#1426199 — [PATCH 0/5] Implement bitlock map allocator

FromByungchul Park <byungchul.park@lge.com>
Date2016-06-20 07:20 +0200
Subject[PATCH 0/5] Implement bitlock map allocator
Message-ID<rLZMR-42g-9@gated-at.bofh.it>
Currently, bit-based lock e.g. bit_spin_lock cannot use the lock
correctness validator using lockdep. However, it would be useful if
the validator supports for even bit-based lock as well.

Therefore, this patch provides interface for allocation and freeing
lockdep_map for bit-based lock so that the bit-based lock can also use
the lock correctness validator with the lockdep_map, allocated for each
bit address.

This patch can be applied to any bit_spin_lock user except slab
allocator where I am not sure if using kmalloc is safe. Anyway I chose
two example to apply bitlock map allocator, zram and buffer head.
And applied it and included it in this patch set.

Byungchul Park (5):
  lockdep: Implement bitlock map allocator
  lockdep: Apply bitlock to bit_spin_lock
  lockdep: Apply bit_spin_lock lockdep to zram
  fs/buffer.c: Remove trailing white space
  lockdep: Apply bit_spin_lock lockdep to BH_Uptodate_Lock

 drivers/block/zram/zram_drv.c |  10 +++
 fs/buffer.c                   |  24 +++----
 include/linux/bit_spinlock.h  |  57 ++++++++++++++--
 include/linux/bitlock.h       |  20 ++++++
 kernel/locking/Makefile       |   1 +
 kernel/locking/bitlock_map.c  | 147 ++++++++++++++++++++++++++++++++++++++++++
 lib/Kconfig.debug             |  10 +++
 7 files changed, 252 insertions(+), 17 deletions(-)
 create mode 100644 include/linux/bitlock.h
 create mode 100644 kernel/locking/bitlock_map.c

-- 
1.9.1

[toc] | [next] | [standalone]


#1426201 — [PATCH 4/5] fs/buffer.c: Remove trailing white space

FromByungchul Park <byungchul.park@lge.com>
Date2016-06-20 07:20 +0200
Subject[PATCH 4/5] fs/buffer.c: Remove trailing white space
Message-ID<rLZMS-42g-43@gated-at.bofh.it>
In reply to#1426199
Trailing white space is not accepted in kernel coding style. Remove
them.

Signed-off-by: Byungchul Park <byungchul.park@lge.com>
---
 fs/buffer.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/fs/buffer.c b/fs/buffer.c
index e1632ab..a75ca74 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -439,7 +439,7 @@ EXPORT_SYMBOL(mark_buffer_async_write);
  * try_to_free_buffers() will be operating against the *blockdev* mapping
  * at the time, not against the S_ISREG file which depends on those buffers.
  * So the locking for private_list is via the private_lock in the address_space
- * which backs the buffers.  Which is different from the address_space 
+ * which backs the buffers.  Which is different from the address_space
  * against which the buffers are listed.  So for a particular address_space,
  * mapping->private_lock does *not* protect mapping->private_list!  In fact,
  * mapping->private_list will always be protected by the backing blockdev's
@@ -713,7 +713,7 @@ EXPORT_SYMBOL(__set_page_dirty_buffers);
  * Do this in two main stages: first we copy dirty buffers to a
  * temporary inode list, queueing the writes as we go.  Then we clean
  * up, waiting for those writes to complete.
- * 
+ *
  * During this second stage, any subsequent updates to the file may end
  * up refiling the buffer on the original inode's dirty list again, so
  * there is a chance we will end up with a buffer queued for write but
@@ -791,7 +791,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list)
 		brelse(bh);
 		spin_lock(lock);
 	}
-	
+
 	spin_unlock(lock);
 	err2 = osync_buffers_list(lock, list);
 	if (err)
@@ -901,7 +901,7 @@ no_grow:
 	/*
 	 * Return failure for non-async IO requests.  Async IO requests
 	 * are not allowed to fail, so we have to wait until buffer heads
-	 * become available.  But we don't want tasks sleeping with 
+	 * become available.  But we don't want tasks sleeping with
 	 * partially complete buffers, so all were released above.
 	 */
 	if (!retry)
@@ -910,7 +910,7 @@ no_grow:
 	/* We're _really_ low on memory. Now we just
 	 * wait for old buffer heads to become free due to
 	 * finishing IO.  Since this is an async request and
-	 * the reserve list is empty, we're sure there are 
+	 * the reserve list is empty, we're sure there are
 	 * async buffer heads in use.
 	 */
 	free_more_memory();
@@ -946,7 +946,7 @@ static sector_t blkdev_max_block(struct block_device *bdev, unsigned int size)
 
 /*
  * Initialise the state of a blockdev page's buffers.
- */ 
+ */
 static sector_t
 init_page_buffers(struct page *page, struct block_device *bdev,
 			sector_t block, int size)
@@ -1448,7 +1448,7 @@ static bool has_bh_in_lru(int cpu, void *dummy)
 {
 	struct bh_lru *b = per_cpu_ptr(&bh_lrus, cpu);
 	int i;
-	
+
 	for (i = 0; i < BH_LRU_SIZE; i++) {
 		if (b->bhs[i])
 			return 1;
@@ -1952,7 +1952,7 @@ int __block_write_begin(struct page *page, loff_t pos, unsigned len,
 		if (PageUptodate(page)) {
 			if (!buffer_uptodate(bh))
 				set_buffer_uptodate(bh);
-			continue; 
+			continue;
 		}
 		if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
 		    !buffer_unwritten(bh) &&
@@ -2258,7 +2258,7 @@ EXPORT_SYMBOL(block_read_full_page);
 
 /* utility function for filesystems that need to do work on expanding
  * truncates.  Uses filesystem pagecache writes to allow the filesystem to
- * deal with the hole.  
+ * deal with the hole.
  */
 int generic_cont_expand_simple(struct inode *inode, loff_t size)
 {
@@ -2819,7 +2819,7 @@ int block_truncate_page(struct address_space *mapping,
 
 	length = blocksize - length;
 	iblock = (sector_t)index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
-	
+
 	page = grab_cache_page(mapping, index);
 	err = -ENOMEM;
 	if (!page)
@@ -3069,7 +3069,7 @@ EXPORT_SYMBOL(submit_bh);
  *
  * ll_rw_block sets b_end_io to simple completion handler that marks
  * the buffer up-to-date (if appropriate), unlocks the buffer and wakes
- * any waiters. 
+ * any waiters.
  *
  * All of the buffers must be for the same device, and must also be a
  * multiple of the current approved size for the device.
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1426203 — [PATCH 2/5] lockdep: Apply bitlock to bit_spin_lock

FromByungchul Park <byungchul.park@lge.com>
Date2016-06-20 07:20 +0200
Subject[PATCH 2/5] lockdep: Apply bitlock to bit_spin_lock
Message-ID<rLZMR-42g-15@gated-at.bofh.it>
In reply to#1426199
Currently, bit_spin_lock does not use lockdep_map at all. Of course,
the lock correctness validator is not supported for bit_spin_lock.
This patch makes bit_spin_lock possible to use the validator using
CONFIG_BITLOCK_ALLOC.

Signed-off-by: Byungchul Park <byungchul.park@lge.com>
---
 include/linux/bit_spinlock.h | 57 +++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 51 insertions(+), 6 deletions(-)

diff --git a/include/linux/bit_spinlock.h b/include/linux/bit_spinlock.h
index 3b5bafc..3f8b013 100644
--- a/include/linux/bit_spinlock.h
+++ b/include/linux/bit_spinlock.h
@@ -6,13 +6,43 @@
 #include <linux/atomic.h>
 #include <linux/bug.h>
 
+#ifdef CONFIG_BITLOCK_ALLOC
+#include <linux/bitlock.h>
+#define bit_spin_init(b, a)			\
+do {						\
+	static struct lock_class_key __key;	\
+	bitlock_init(b, a, #b "@" #a, &__key);	\
+} while (0)
+
+static inline void bit_spin_free(int bitnum, unsigned long *addr)
+{
+	bitlock_free(bitnum, addr);
+}
+
+static inline void bit_spin_acquire(int bitnum, unsigned long *addr, int try)
+{
+	struct lockdep_map *map = bitlock_get_map(bitnum, addr, BIT_ACQUIRE);
+	if (map)
+		spin_acquire(map, 0, try, _RET_IP_);
+}
+
+static inline void bit_spin_release(int bitnum, unsigned long *addr)
+{
+	struct lockdep_map *map = bitlock_get_map(bitnum, addr, BIT_RELEASE);
+	if (map)
+		spin_release(map, 0, _RET_IP_);
+}
+#else
+static inline void bit_spin_init(int bitnum, unsigned long *addr) {}
+static inline void bit_spin_free(int bitnum, unsigned long *addr) {}
+static inline void bit_spin_acquire(int bitnum, unsigned long *addr, int try) {}
+static inline void bit_spin_release(int bitnum, unsigned long *addr) {}
+#endif
+
 /*
- *  bit-based spin_lock()
- *
- * Don't use this unless you really need to: spin_lock() and spin_unlock()
- * are significantly faster.
+ * bit-based spin_lock() without lock acquiring
  */
-static inline void bit_spin_lock(int bitnum, unsigned long *addr)
+static inline void do_raw_bit_spin_lock(int bitnum, unsigned long *addr)
 {
 	/*
 	 * Assuming the lock is uncontended, this never enters
@@ -21,7 +51,6 @@ static inline void bit_spin_lock(int bitnum, unsigned long *addr)
 	 * busywait with less bus contention for a good time to
 	 * attempt to acquire the lock bit.
 	 */
-	preempt_disable();
 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
 	while (unlikely(test_and_set_bit_lock(bitnum, addr))) {
 		preempt_enable();
@@ -35,6 +64,19 @@ static inline void bit_spin_lock(int bitnum, unsigned long *addr)
 }
 
 /*
+ *  bit-based spin_lock()
+ *
+ * Don't use this unless you really need to: spin_lock() and spin_unlock()
+ * are significantly faster.
+ */
+static inline void bit_spin_lock(int bitnum, unsigned long *addr)
+{
+	preempt_disable();
+	bit_spin_acquire(bitnum, addr, 0);
+	do_raw_bit_spin_lock(bitnum, addr);
+}
+
+/*
  * Return true if it was acquired
  */
 static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
@@ -46,6 +88,7 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
 		return 0;
 	}
 #endif
+	bit_spin_acquire(bitnum, addr, 1);
 	__acquire(bitlock);
 	return 1;
 }
@@ -55,6 +98,7 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
  */
 static inline void bit_spin_unlock(int bitnum, unsigned long *addr)
 {
+	bit_spin_release(bitnum, addr);
 #ifdef CONFIG_DEBUG_SPINLOCK
 	BUG_ON(!test_bit(bitnum, addr));
 #endif
@@ -72,6 +116,7 @@ static inline void bit_spin_unlock(int bitnum, unsigned long *addr)
  */
 static inline void __bit_spin_unlock(int bitnum, unsigned long *addr)
 {
+	bit_spin_release(bitnum, addr);
 #ifdef CONFIG_DEBUG_SPINLOCK
 	BUG_ON(!test_bit(bitnum, addr));
 #endif
-- 
1.9.1

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web