172 lines
5.2 KiB
Diff
172 lines
5.2 KiB
Diff
|
From f445e378781da92e599d3d9ebecf71d73001f6a4 Mon Sep 17 00:00:00 2001
|
||
|
From: Thomas Gleixner <tglx@linutronix.de>
|
||
|
Date: Fri, 18 Mar 2011 09:18:52 +0100
|
||
|
Subject: [PATCH 092/365] buffer_head: Replace bh_uptodate_lock for -rt
|
||
|
|
||
|
Wrap the bit_spin_lock calls into a separate inline and add the RT
|
||
|
replacements with a real spinlock.
|
||
|
|
||
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
||
|
---
|
||
|
fs/buffer.c | 21 +++++++--------------
|
||
|
fs/ntfs/aops.c | 10 +++-------
|
||
|
include/linux/buffer_head.h | 34 ++++++++++++++++++++++++++++++++++
|
||
|
3 files changed, 44 insertions(+), 21 deletions(-)
|
||
|
|
||
|
diff --git a/fs/buffer.c b/fs/buffer.c
|
||
|
index 681b249039eb..c769b1573fb0 100644
|
||
|
--- a/fs/buffer.c
|
||
|
+++ b/fs/buffer.c
|
||
|
@@ -302,8 +302,7 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
|
||
|
* decide that the page is now completely done.
|
||
|
*/
|
||
|
first = page_buffers(page);
|
||
|
- local_irq_save(flags);
|
||
|
- bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
|
||
|
+ flags = bh_uptodate_lock_irqsave(first);
|
||
|
clear_buffer_async_read(bh);
|
||
|
unlock_buffer(bh);
|
||
|
tmp = bh;
|
||
|
@@ -316,8 +315,7 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
|
||
|
}
|
||
|
tmp = tmp->b_this_page;
|
||
|
} while (tmp != bh);
|
||
|
- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
|
||
|
- local_irq_restore(flags);
|
||
|
+ bh_uptodate_unlock_irqrestore(first, flags);
|
||
|
|
||
|
/*
|
||
|
* If none of the buffers had errors and they are all
|
||
|
@@ -329,9 +327,7 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
|
||
|
return;
|
||
|
|
||
|
still_busy:
|
||
|
- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
|
||
|
- local_irq_restore(flags);
|
||
|
- return;
|
||
|
+ bh_uptodate_unlock_irqrestore(first, flags);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
@@ -359,8 +355,7 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate)
|
||
|
}
|
||
|
|
||
|
first = page_buffers(page);
|
||
|
- local_irq_save(flags);
|
||
|
- bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
|
||
|
+ flags = bh_uptodate_lock_irqsave(first);
|
||
|
|
||
|
clear_buffer_async_write(bh);
|
||
|
unlock_buffer(bh);
|
||
|
@@ -372,15 +367,12 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate)
|
||
|
}
|
||
|
tmp = tmp->b_this_page;
|
||
|
}
|
||
|
- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
|
||
|
- local_irq_restore(flags);
|
||
|
+ bh_uptodate_unlock_irqrestore(first, flags);
|
||
|
end_page_writeback(page);
|
||
|
return;
|
||
|
|
||
|
still_busy:
|
||
|
- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
|
||
|
- local_irq_restore(flags);
|
||
|
- return;
|
||
|
+ bh_uptodate_unlock_irqrestore(first, flags);
|
||
|
}
|
||
|
EXPORT_SYMBOL(end_buffer_async_write);
|
||
|
|
||
|
@@ -3384,6 +3376,7 @@ struct buffer_head *alloc_buffer_head(gfp_t gfp_flags)
|
||
|
struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags);
|
||
|
if (ret) {
|
||
|
INIT_LIST_HEAD(&ret->b_assoc_buffers);
|
||
|
+ buffer_head_init_locks(ret);
|
||
|
preempt_disable();
|
||
|
__this_cpu_inc(bh_accounting.nr);
|
||
|
recalc_bh_state();
|
||
|
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
|
||
|
index fe251f187ff8..8bb79f5fda59 100644
|
||
|
--- a/fs/ntfs/aops.c
|
||
|
+++ b/fs/ntfs/aops.c
|
||
|
@@ -107,8 +107,7 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
|
||
|
"0x%llx.", (unsigned long long)bh->b_blocknr);
|
||
|
}
|
||
|
first = page_buffers(page);
|
||
|
- local_irq_save(flags);
|
||
|
- bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
|
||
|
+ flags = bh_uptodate_lock_irqsave(first);
|
||
|
clear_buffer_async_read(bh);
|
||
|
unlock_buffer(bh);
|
||
|
tmp = bh;
|
||
|
@@ -123,8 +122,7 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
|
||
|
}
|
||
|
tmp = tmp->b_this_page;
|
||
|
} while (tmp != bh);
|
||
|
- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
|
||
|
- local_irq_restore(flags);
|
||
|
+ bh_uptodate_unlock_irqrestore(first, flags);
|
||
|
/*
|
||
|
* If none of the buffers had errors then we can set the page uptodate,
|
||
|
* but we first have to perform the post read mst fixups, if the
|
||
|
@@ -159,9 +157,7 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
|
||
|
unlock_page(page);
|
||
|
return;
|
||
|
still_busy:
|
||
|
- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
|
||
|
- local_irq_restore(flags);
|
||
|
- return;
|
||
|
+ bh_uptodate_unlock_irqrestore(first, flags);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
|
||
|
index 4431ea2c8802..87c4ed37ee77 100644
|
||
|
--- a/include/linux/buffer_head.h
|
||
|
+++ b/include/linux/buffer_head.h
|
||
|
@@ -75,8 +75,42 @@ struct buffer_head {
|
||
|
struct address_space *b_assoc_map; /* mapping this buffer is
|
||
|
associated with */
|
||
|
atomic_t b_count; /* users using this buffer_head */
|
||
|
+#ifdef CONFIG_PREEMPT_RT_BASE
|
||
|
+ spinlock_t b_uptodate_lock;
|
||
|
+#endif
|
||
|
};
|
||
|
|
||
|
+static inline unsigned long bh_uptodate_lock_irqsave(struct buffer_head *bh)
|
||
|
+{
|
||
|
+ unsigned long flags;
|
||
|
+
|
||
|
+#ifndef CONFIG_PREEMPT_RT_BASE
|
||
|
+ local_irq_save(flags);
|
||
|
+ bit_spin_lock(BH_Uptodate_Lock, &bh->b_state);
|
||
|
+#else
|
||
|
+ spin_lock_irqsave(&bh->b_uptodate_lock, flags);
|
||
|
+#endif
|
||
|
+ return flags;
|
||
|
+}
|
||
|
+
|
||
|
+static inline void
|
||
|
+bh_uptodate_unlock_irqrestore(struct buffer_head *bh, unsigned long flags)
|
||
|
+{
|
||
|
+#ifndef CONFIG_PREEMPT_RT_BASE
|
||
|
+ bit_spin_unlock(BH_Uptodate_Lock, &bh->b_state);
|
||
|
+ local_irq_restore(flags);
|
||
|
+#else
|
||
|
+ spin_unlock_irqrestore(&bh->b_uptodate_lock, flags);
|
||
|
+#endif
|
||
|
+}
|
||
|
+
|
||
|
+static inline void buffer_head_init_locks(struct buffer_head *bh)
|
||
|
+{
|
||
|
+#ifdef CONFIG_PREEMPT_RT_BASE
|
||
|
+ spin_lock_init(&bh->b_uptodate_lock);
|
||
|
+#endif
|
||
|
+}
|
||
|
+
|
||
|
/*
|
||
|
* macro tricks to expand the set_buffer_foo(), clear_buffer_foo()
|
||
|
* and buffer_foo() functions.
|
||
|
--
|
||
|
2.28.0
|
||
|
|