172 lines
5.1 KiB
Diff
172 lines
5.1 KiB
Diff
From 102af809f9709c00543fddb164bf9172a17aee07 Mon Sep 17 00:00:00 2001
|
|
From: Thomas Gleixner <tglx@linutronix.de>
|
|
Date: Fri, 18 Mar 2011 09:18:52 +0100
|
|
Subject: [PATCH 094/278] 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 4115eca..039fbba 100644
|
|
--- a/fs/buffer.c
|
|
+++ b/fs/buffer.c
|
|
@@ -331,8 +331,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;
|
|
@@ -345,8 +344,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
|
|
@@ -358,9 +356,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);
|
|
}
|
|
|
|
/*
|
|
@@ -394,8 +390,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);
|
|
@@ -407,15 +402,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);
|
|
|
|
@@ -3229,6 +3221,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 0b1e885b..7fb7f1b 100644
|
|
--- a/fs/ntfs/aops.c
|
|
+++ b/fs/ntfs/aops.c
|
|
@@ -108,8 +108,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;
|
|
@@ -124,8 +123,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
|
|
@@ -160,9 +158,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 458f497..5c16cf1 100644
|
|
--- a/include/linux/buffer_head.h
|
|
+++ b/include/linux/buffer_head.h
|
|
@@ -72,8 +72,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.
|
|
--
|
|
1.7.10
|
|
|