forked from rrcarlosr/Jetpack
172 lines
5.1 KiB
Diff
172 lines
5.1 KiB
Diff
From 552c5414e222783b3517719a79d1fc7e1dc439b0 Mon Sep 17 00:00:00 2001
|
|
From: Thomas Gleixner <tglx@linutronix.de>
|
|
Date: Fri, 18 Mar 2011 09:18:52 +0100
|
|
Subject: [PATCH 093/352] 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 5d8f496..48074bd 100644
|
|
--- a/fs/buffer.c
|
|
+++ b/fs/buffer.c
|
|
@@ -301,8 +301,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;
|
|
@@ -315,8 +314,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
|
|
@@ -328,9 +326,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);
|
|
}
|
|
|
|
/*
|
|
@@ -358,8 +354,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);
|
|
@@ -371,15 +366,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);
|
|
|
|
@@ -3383,6 +3375,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 fe251f1..8bb79f5 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 4431ea2..87c4ed3 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.7.4
|
|
|