[rt] bump version to 3.2.12-rt22

This undoes the locking change to struct fs, so the corresponding fixups
can be dropped, too.

svn path=/dists/sid/linux-2.6/; revision=18881
This commit is contained in:
Uwe Kleine-König 2012-03-24 00:48:38 +00:00
parent 54502859ca
commit a02f2f02e0
16 changed files with 234 additions and 3674 deletions

4
debian/changelog vendored
View File

@ -1,7 +1,11 @@
linux-2.6 (3.2.12-2) UNRELEASED; urgency=low
[ Ben Hutchings ]
* kbuild: do not check for ancient modutils tools
[ Uwe Kleine-König ]
* [rt] bump version to 3.2.12-rt22
-- Ben Hutchings <ben@decadent.org.uk> Wed, 21 Mar 2012 03:15:13 +0000
linux-2.6 (3.2.12-1) unstable; urgency=high

View File

@ -12,20 +12,20 @@ Remove it.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 7 ++-----
drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 6 +-----
drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 3 +--
drivers/net/ethernet/chelsio/cxgb/sge.c | 3 +--
drivers/net/ethernet/neterion/s2io.c | 7 +------
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 7 +++----
drivers/net/ethernet/tehuti/tehuti.c | 9 ++-------
drivers/net/rionet.c | 6 +-----
7 files changed, 11 insertions(+), 31 deletions(-)
7 files changed, 10 insertions(+), 31 deletions(-)
Index: linux-3.2/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
===================================================================
--- linux-3.2.orig/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ linux-3.2/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -2236,11 +2236,8 @@ static netdev_tx_t atl1c_xmit_frame(stru
@@ -2236,11 +2236,7 @@ static netdev_tx_t atl1c_xmit_frame(stru
}
tpd_req = atl1c_cal_tpd_req(skb);
@ -35,7 +35,6 @@ Index: linux-3.2/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
- return NETDEV_TX_LOCKED;
- }
+ spin_lock_irqsave(&adapter->tx_lock, flags);
+
if (atl1c_tpd_avail(adapter, type) < tpd_req) {
/* no enough descriptor, just stop queue */

View File

@ -1,22 +0,0 @@
---
fs/namei.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -679,13 +679,13 @@
return 0;
/* Check parent directory mode and owner. */
- spin_lock(&dentry->d_lock);
+ seq_spin_lock(&dentry->d_lock);
parent = dentry->d_parent->d_inode;
if ((parent->i_mode & (S_ISVTX|S_IWOTH)) == (S_ISVTX|S_IWOTH) &&
parent->i_uid != inode->i_uid) {
error = -EACCES;
}
- spin_unlock(&dentry->d_lock);
+ seq_spin_unlock(&dentry->d_lock);
if (error)
audit_log_link_denied("follow_link", link);

View File

@ -12,7 +12,8 @@ Cc: stable-rt@vger.kernel.org
fs/autofs4/autofs_i.h | 1 +
fs/autofs4/expire.c | 2 +-
fs/dcache.c | 7 ++++---
3 files changed, 6 insertions(+), 4 deletions(-)
fs/namespace.c | 3 ++-
4 files changed, 8 insertions(+), 5 deletions(-)
Index: linux-3.2/fs/autofs4/autofs_i.h
===================================================================
@ -32,13 +33,13 @@ Index: linux-3.2/fs/autofs4/expire.c
+++ linux-3.2/fs/autofs4/expire.c
@@ -170,7 +170,7 @@ again:
parent = p->d_parent;
if (!seq_spin_trylock(&parent->d_lock)) {
seq_spin_unlock(&p->d_lock);
if (!spin_trylock(&parent->d_lock)) {
spin_unlock(&p->d_lock);
- cpu_relax();
+ cpu_chill();
goto relock;
}
seq_spin_unlock(&p->d_lock);
spin_unlock(&p->d_lock);
Index: linux-3.2/fs/dcache.c
===================================================================
--- linux-3.2.orig/fs/dcache.c
@ -54,7 +55,7 @@ Index: linux-3.2/fs/dcache.c
@@ -410,7 +411,7 @@ static inline struct dentry *dentry_kill
if (inode && !spin_trylock(&inode->i_lock)) {
relock:
seq_spin_unlock(&dentry->d_lock);
spin_unlock(&dentry->d_lock);
- cpu_relax();
+ cpu_chill();
return dentry; /* try again with same dentry */
@ -62,19 +63,40 @@ Index: linux-3.2/fs/dcache.c
if (IS_ROOT(dentry))
@@ -796,7 +797,7 @@ relock:
if (!seq_spin_trylock(&dentry->d_lock)) {
if (!spin_trylock(&dentry->d_lock)) {
spin_unlock(&dcache_lru_lock);
- cpu_relax();
+ cpu_chill();
goto relock;
}
@@ -1974,7 +1975,7 @@ again:
@@ -1975,7 +1976,7 @@ again:
if (dentry->d_count == 1) {
if (inode && !spin_trylock(&inode->i_lock)) {
seq_spin_unlock(&dentry->d_lock);
spin_unlock(&dentry->d_lock);
- cpu_relax();
+ cpu_chill();
goto again;
}
dentry->d_flags &= ~DCACHE_CANT_MOUNT;
Index: linux-3.2/fs/namespace.c
===================================================================
--- linux-3.2.orig/fs/namespace.c
+++ linux-3.2/fs/namespace.c
@@ -31,6 +31,7 @@
#include <linux/idr.h>
#include <linux/fs_struct.h>
#include <linux/fsnotify.h>
+#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
#include "pnode.h"
@@ -346,7 +347,7 @@ int mnt_want_write(struct vfsmount *mnt)
*/
while (mnt->mnt_flags & MNT_WRITE_HOLD) {
preempt_enable();
- cpu_relax();
+ cpu_chill();
preempt_disable();
}
/*

File diff suppressed because it is too large Load Diff

View File

@ -1,35 +0,0 @@
Subject: fs: namespace: Use cpu_chill() instead of cpu_relax()
From: Thomas Gleixner <tglx@linutronix.de>
Date: Wed, 07 Mar 2012 21:05:19 +0100
Retry loops on RT might loop forever when the modifying side was
preempted. Use cpu_chill() instead of cpu_relax() to let the system
make progress.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable-rt@vger.kernel.org
---
fs/namespace.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Index: linux-3.2/fs/namespace.c
===================================================================
--- linux-3.2.orig/fs/namespace.c
+++ linux-3.2/fs/namespace.c
@@ -31,6 +31,7 @@
#include <linux/idr.h>
#include <linux/fs_struct.h>
#include <linux/fsnotify.h>
+#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
#include "pnode.h"
@@ -346,7 +347,7 @@ int mnt_want_write(struct vfsmount *mnt)
*/
while (mnt->mnt_flags & MNT_WRITE_HOLD) {
preempt_enable();
- cpu_relax();
+ cpu_chill();
preempt_disable();
}
/*

View File

@ -1,31 +0,0 @@
Subject: fs: Protect open coded isize seqcount
From: Thomas Gleixner <tglx@linutronix.de>
Date: Thu, 01 Mar 2012 16:12:47 +0100
A writer might be preempted in the write side critical section on
RT. Disable preemption to avoid endless spinning of a preempting
reader.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable-rt@vger.kernel.org
---
include/linux/fs.h | 2 ++
1 file changed, 2 insertions(+)
Index: linux-3.2/include/linux/fs.h
===================================================================
--- linux-3.2.orig/include/linux/fs.h
+++ linux-3.2/include/linux/fs.h
@@ -903,9 +903,11 @@ static inline loff_t i_size_read(const s
static inline void i_size_write(struct inode *inode, loff_t i_size)
{
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
+ preempt_disable_rt();
write_seqcount_begin(&inode->i_size_seqcount);
inode->i_size = i_size;
write_seqcount_end(&inode->i_size_seqcount);
+ preempt_enable_rt();
#elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPT)
preempt_disable();
inode->i_size = i_size;

View File

@ -1,339 +0,0 @@
Subject: fs: fs_struct use seqlock
From: Thomas Gleixner <tglx@linutronix.de>
Date: Mon, 27 Feb 2012 17:58:13 +0100
Replace the open coded seqlock with a real one, so RT can handle it.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable-rt@vger.kernel.org
---
fs/exec.c | 4 ++--
fs/fhandle.c | 4 ++--
fs/fs_struct.c | 46 ++++++++++++++++++----------------------------
fs/namei.c | 14 +++++++-------
include/linux/fs_struct.h | 16 +++++++---------
kernel/fork.c | 10 +++++-----
6 files changed, 41 insertions(+), 53 deletions(-)
Index: linux-3.2/fs/exec.c
===================================================================
--- linux-3.2.orig/fs/exec.c
+++ linux-3.2/fs/exec.c
@@ -1239,7 +1239,7 @@ int check_unsafe_exec(struct linux_binpr
}
n_fs = 1;
- spin_lock(&p->fs->lock);
+ seq_spin_lock(&p->fs->lock);
rcu_read_lock();
for (t = next_thread(p); t != p; t = next_thread(t)) {
if (t->fs == p->fs)
@@ -1256,7 +1256,7 @@ int check_unsafe_exec(struct linux_binpr
res = 1;
}
}
- spin_unlock(&p->fs->lock);
+ seq_spin_unlock(&p->fs->lock);
return res;
}
Index: linux-3.2/fs/fhandle.c
===================================================================
--- linux-3.2.orig/fs/fhandle.c
+++ linux-3.2/fs/fhandle.c
@@ -115,10 +115,10 @@ static struct vfsmount *get_vfsmount_fro
if (fd == AT_FDCWD) {
struct fs_struct *fs = current->fs;
- spin_lock(&fs->lock);
+ seq_spin_lock(&fs->lock);
path = fs->pwd;
mntget(path.mnt);
- spin_unlock(&fs->lock);
+ seq_spin_unlock(&fs->lock);
} else {
int fput_needed;
struct file *file = fget_light(fd, &fput_needed);
Index: linux-3.2/fs/fs_struct.c
===================================================================
--- linux-3.2.orig/fs/fs_struct.c
+++ linux-3.2/fs/fs_struct.c
@@ -26,13 +26,11 @@ void set_fs_root(struct fs_struct *fs, s
{
struct path old_root;
- spin_lock(&fs->lock);
- write_seqcount_begin(&fs->seq);
+ write_seqlock(&fs->lock);
old_root = fs->root;
fs->root = *path;
path_get_longterm(path);
- write_seqcount_end(&fs->seq);
- spin_unlock(&fs->lock);
+ write_sequnlock(&fs->lock);
if (old_root.dentry)
path_put_longterm(&old_root);
}
@@ -45,13 +43,11 @@ void set_fs_pwd(struct fs_struct *fs, st
{
struct path old_pwd;
- spin_lock(&fs->lock);
- write_seqcount_begin(&fs->seq);
+ write_seqlock(&fs->lock);
old_pwd = fs->pwd;
fs->pwd = *path;
path_get_longterm(path);
- write_seqcount_end(&fs->seq);
- spin_unlock(&fs->lock);
+ write_sequnlock(&fs->lock);
if (old_pwd.dentry)
path_put_longterm(&old_pwd);
@@ -68,8 +64,7 @@ void chroot_fs_refs(struct path *old_roo
task_lock(p);
fs = p->fs;
if (fs) {
- spin_lock(&fs->lock);
- write_seqcount_begin(&fs->seq);
+ write_seqlock(&fs->lock);
if (fs->root.dentry == old_root->dentry
&& fs->root.mnt == old_root->mnt) {
path_get_longterm(new_root);
@@ -82,8 +77,7 @@ void chroot_fs_refs(struct path *old_roo
fs->pwd = *new_root;
count++;
}
- write_seqcount_end(&fs->seq);
- spin_unlock(&fs->lock);
+ write_sequnlock(&fs->lock);
}
task_unlock(p);
} while_each_thread(g, p);
@@ -106,12 +100,10 @@ void exit_fs(struct task_struct *tsk)
if (fs) {
int kill;
task_lock(tsk);
- spin_lock(&fs->lock);
- write_seqcount_begin(&fs->seq);
+ write_seqlock(&fs->lock);
tsk->fs = NULL;
kill = !--fs->users;
- write_seqcount_end(&fs->seq);
- spin_unlock(&fs->lock);
+ write_sequnlock(&fs->lock);
task_unlock(tsk);
if (kill)
free_fs_struct(fs);
@@ -125,16 +117,15 @@ struct fs_struct *copy_fs_struct(struct
if (fs) {
fs->users = 1;
fs->in_exec = 0;
- spin_lock_init(&fs->lock);
- seqcount_init(&fs->seq);
+ seqlock_init(&fs->lock);
fs->umask = old->umask;
- spin_lock(&old->lock);
+ seq_spin_lock(&old->lock);
fs->root = old->root;
path_get_longterm(&fs->root);
fs->pwd = old->pwd;
path_get_longterm(&fs->pwd);
- spin_unlock(&old->lock);
+ seq_spin_unlock(&old->lock);
}
return fs;
}
@@ -149,10 +140,10 @@ int unshare_fs_struct(void)
return -ENOMEM;
task_lock(current);
- spin_lock(&fs->lock);
+ seq_spin_lock(&fs->lock);
kill = !--fs->users;
current->fs = new_fs;
- spin_unlock(&fs->lock);
+ seq_spin_unlock(&fs->lock);
task_unlock(current);
if (kill)
@@ -171,8 +162,7 @@ EXPORT_SYMBOL(current_umask);
/* to be mentioned only in INIT_TASK */
struct fs_struct init_fs = {
.users = 1,
- .lock = __SPIN_LOCK_UNLOCKED(init_fs.lock),
- .seq = SEQCNT_ZERO,
+ .lock = __SEQLOCK_UNLOCKED(init_fs.lock),
.umask = 0022,
};
@@ -185,14 +175,14 @@ void daemonize_fs_struct(void)
task_lock(current);
- spin_lock(&init_fs.lock);
+ seq_spin_lock(&init_fs.lock);
init_fs.users++;
- spin_unlock(&init_fs.lock);
+ seq_spin_unlock(&init_fs.lock);
- spin_lock(&fs->lock);
+ seq_spin_lock(&fs->lock);
current->fs = &init_fs;
kill = !--fs->users;
- spin_unlock(&fs->lock);
+ seq_spin_unlock(&fs->lock);
task_unlock(current);
if (kill)
Index: linux-3.2/fs/namei.c
===================================================================
--- linux-3.2.orig/fs/namei.c
+++ linux-3.2/fs/namei.c
@@ -428,7 +428,7 @@ static int unlazy_walk(struct nameidata
BUG_ON(!(nd->flags & LOOKUP_RCU));
if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) {
want_root = 1;
- spin_lock(&fs->lock);
+ seq_spin_lock(&fs->lock);
if (nd->root.mnt != fs->root.mnt ||
nd->root.dentry != fs->root.dentry)
goto err_root;
@@ -458,7 +458,7 @@ static int unlazy_walk(struct nameidata
spin_unlock(&parent->d_lock);
if (want_root) {
path_get(&nd->root);
- spin_unlock(&fs->lock);
+ seq_spin_unlock(&fs->lock);
}
mntget(nd->path.mnt);
@@ -473,7 +473,7 @@ err_parent:
spin_unlock(&parent->d_lock);
err_root:
if (want_root)
- spin_unlock(&fs->lock);
+ seq_spin_unlock(&fs->lock);
return -ECHILD;
}
@@ -567,10 +567,10 @@ static __always_inline void set_root_rcu
unsigned seq;
do {
- seq = read_seqcount_begin(&fs->seq);
+ seq = read_seqbegin(&fs->lock);
nd->root = fs->root;
nd->seq = __read_seqcount_begin(&nd->root.dentry->d_seq);
- } while (read_seqcount_retry(&fs->seq, seq));
+ } while (read_seqretry(&fs->lock, seq));
}
}
@@ -1519,10 +1519,10 @@ static int path_init(int dfd, const char
rcu_read_lock();
do {
- seq = read_seqcount_begin(&fs->seq);
+ seq = read_seqbegin(&fs->lock);
nd->path = fs->pwd;
nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
- } while (read_seqcount_retry(&fs->seq, seq));
+ } while (read_seqretry(&fs->lock, seq));
} else {
get_fs_pwd(current->fs, &nd->path);
}
Index: linux-3.2/include/linux/fs_struct.h
===================================================================
--- linux-3.2.orig/include/linux/fs_struct.h
+++ linux-3.2/include/linux/fs_struct.h
@@ -2,13 +2,11 @@
#define _LINUX_FS_STRUCT_H
#include <linux/path.h>
-#include <linux/spinlock.h>
#include <linux/seqlock.h>
struct fs_struct {
int users;
- spinlock_t lock;
- seqcount_t seq;
+ seqlock_t lock;
int umask;
int in_exec;
struct path root, pwd;
@@ -26,29 +24,29 @@ extern int unshare_fs_struct(void);
static inline void get_fs_root(struct fs_struct *fs, struct path *root)
{
- spin_lock(&fs->lock);
+ seq_spin_lock(&fs->lock);
*root = fs->root;
path_get(root);
- spin_unlock(&fs->lock);
+ seq_spin_unlock(&fs->lock);
}
static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd)
{
- spin_lock(&fs->lock);
+ seq_spin_lock(&fs->lock);
*pwd = fs->pwd;
path_get(pwd);
- spin_unlock(&fs->lock);
+ seq_spin_unlock(&fs->lock);
}
static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root,
struct path *pwd)
{
- spin_lock(&fs->lock);
+ seq_spin_lock(&fs->lock);
*root = fs->root;
path_get(root);
*pwd = fs->pwd;
path_get(pwd);
- spin_unlock(&fs->lock);
+ seq_spin_unlock(&fs->lock);
}
#endif /* _LINUX_FS_STRUCT_H */
Index: linux-3.2/kernel/fork.c
===================================================================
--- linux-3.2.orig/kernel/fork.c
+++ linux-3.2/kernel/fork.c
@@ -825,13 +825,13 @@ static int copy_fs(unsigned long clone_f
struct fs_struct *fs = current->fs;
if (clone_flags & CLONE_FS) {
/* tsk->fs is already what we want */
- spin_lock(&fs->lock);
+ seq_spin_lock(&fs->lock);
if (fs->in_exec) {
- spin_unlock(&fs->lock);
+ seq_spin_unlock(&fs->lock);
return -EAGAIN;
}
fs->users++;
- spin_unlock(&fs->lock);
+ seq_spin_unlock(&fs->lock);
return 0;
}
tsk->fs = copy_fs_struct(fs);
@@ -1717,13 +1717,13 @@ SYSCALL_DEFINE1(unshare, unsigned long,
if (new_fs) {
fs = current->fs;
- spin_lock(&fs->lock);
+ seq_spin_lock(&fs->lock);
current->fs = new_fs;
if (--fs->users)
new_fs = NULL;
else
new_fs = fs;
- spin_unlock(&fs->lock);
+ seq_spin_unlock(&fs->lock);
}
if (new_fd) {

View File

@ -14,4 +14,4 @@ Index: linux-3.2/localversion-rt
--- /dev/null
+++ linux-3.2/localversion-rt
@@ -0,0 +1 @@
+-rt20
+-rt22

View File

@ -1,34 +0,0 @@
Subject: net: u64_stat: Protect seqcount
From: Thomas Gleixner <tglx@linutronix.de>
Date: Thu, 01 Mar 2012 16:16:02 +0100
On RT we must prevent that the writer gets preempted inside the write
section. Otherwise a preempting reader might spin forever.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable-rt@vger.kernel.org
---
include/linux/u64_stats_sync.h | 2 ++
1 file changed, 2 insertions(+)
Index: linux-3.2/include/linux/u64_stats_sync.h
===================================================================
--- linux-3.2.orig/include/linux/u64_stats_sync.h
+++ linux-3.2/include/linux/u64_stats_sync.h
@@ -70,6 +70,7 @@ struct u64_stats_sync {
static inline void u64_stats_update_begin(struct u64_stats_sync *syncp)
{
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
+ preempt_disable_rt();
write_seqcount_begin(&syncp->seq);
#endif
}
@@ -78,6 +79,7 @@ static inline void u64_stats_update_end(
{
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
write_seqcount_end(&syncp->seq);
+ preempt_enable_rt();
#endif
}

View File

@ -9,19 +9,56 @@ To prevent this let the reader grab the spinlock, so it blocks and
eventually boosts the writer. This way the writer can proceed and
endless spinning is prevented.
For seqcount writers we disable preemption over the update code
path. Thaanks to Al Viro for distangling some VFS code to make that
possible.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable-rt@vger.kernel.org
---
include/linux/seqlock.h | 23 +++++++++++++++++++++++
include/net/neighbour.h | 2 +-
2 files changed, 24 insertions(+), 1 deletion(-)
include/linux/seqlock.h | 55 +++++++++++++++++++++++++++++++++++++++---------
include/net/neighbour.h | 2 -
2 files changed, 46 insertions(+), 11 deletions(-)
Index: linux-3.2/include/linux/seqlock.h
===================================================================
--- linux-3.2.orig/include/linux/seqlock.h
+++ linux-3.2/include/linux/seqlock.h
@@ -177,10 +177,33 @@ typedef struct {
@@ -125,18 +125,30 @@ static inline int read_seqcount_retry(co
* Sequence counter only version assumes that callers are using their
* own mutexing.
*/
-static inline void write_seqcount_begin(seqcount_t *s)
+static inline void __write_seqcount_begin(seqcount_t *s)
{
s->sequence++;
smp_wmb();
}
-static inline void write_seqcount_end(seqcount_t *s)
+static inline void write_seqcount_begin(seqcount_t *s)
+{
+ preempt_disable_rt();
+ __write_seqcount_begin(s);
+}
+
+static inline void __write_seqcount_end(seqcount_t *s)
{
smp_wmb();
s->sequence++;
}
+static inline void write_seqcount_end(seqcount_t *s)
+{
+ __write_seqcount_end(s);
+ preempt_enable_rt();
+}
+
/**
* write_seqcount_barrier - invalidate in-progress read-side seq operations
* @s: pointer to seqcount_t
@@ -177,10 +189,33 @@ typedef struct {
/*
* Read side functions for starting and finalizing a read side section.
*/
@ -55,6 +92,67 @@ Index: linux-3.2/include/linux/seqlock.h
static inline unsigned read_seqretry(const seqlock_t *sl, unsigned start)
{
@@ -195,36 +230,36 @@ static inline unsigned read_seqretry(con
static inline void write_seqlock(seqlock_t *sl)
{
spin_lock(&sl->lock);
- write_seqcount_begin(&sl->seqcount);
+ __write_seqcount_begin(&sl->seqcount);
}
static inline void write_sequnlock(seqlock_t *sl)
{
- write_seqcount_end(&sl->seqcount);
+ __write_seqcount_end(&sl->seqcount);
spin_unlock(&sl->lock);
}
static inline void write_seqlock_bh(seqlock_t *sl)
{
spin_lock_bh(&sl->lock);
- write_seqcount_begin(&sl->seqcount);
+ __write_seqcount_begin(&sl->seqcount);
}
static inline void write_sequnlock_bh(seqlock_t *sl)
{
- write_seqcount_end(&sl->seqcount);
+ __write_seqcount_end(&sl->seqcount);
spin_unlock_bh(&sl->lock);
}
static inline void write_seqlock_irq(seqlock_t *sl)
{
spin_lock_irq(&sl->lock);
- write_seqcount_begin(&sl->seqcount);
+ __write_seqcount_begin(&sl->seqcount);
}
static inline void write_sequnlock_irq(seqlock_t *sl)
{
- write_seqcount_end(&sl->seqcount);
+ __write_seqcount_end(&sl->seqcount);
spin_unlock_irq(&sl->lock);
}
@@ -233,7 +268,7 @@ static inline unsigned long __write_seql
unsigned long flags;
spin_lock_irqsave(&sl->lock, flags);
- write_seqcount_begin(&sl->seqcount);
+ __write_seqcount_begin(&sl->seqcount);
return flags;
}
@@ -243,7 +278,7 @@ static inline unsigned long __write_seql
static inline void
write_sequnlock_irqrestore(seqlock_t *sl, unsigned long flags)
{
- write_seqcount_end(&sl->seqcount);
+ __write_seqcount_end(&sl->seqcount);
spin_unlock_irqrestore(&sl->lock, flags);
}
Index: linux-3.2/include/net/neighbour.h
===================================================================
--- linux-3.2.orig/include/net/neighbour.h

View File

@ -1,94 +0,0 @@
Subject: seqlock: Provide seq_spin_* functions
From: Thomas Gleixner <tglx@linutronix.de>
Date: Mon, 27 Feb 2012 17:55:11 +0100
In some cases it's desirable to lock the seqlock w/o changing the
seqcount. Provide functions for this, so we can avoid open coded
constructs.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable-rt@vger.kernel.org
---
include/linux/seqlock.h | 64 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
Index: rt/include/linux/seqlock.h
===================================================================
--- rt.orig/include/linux/seqlock.h
+++ rt/include/linux/seqlock.h
@@ -188,6 +188,19 @@ static inline unsigned read_seqretry(con
}
/*
+ * Ditto w/o barriers
+ */
+static inline unsigned __read_seqbegin(const seqlock_t *sl)
+{
+ return __read_seqcount_begin(&sl->seqcount);
+}
+
+static inline unsigned __read_seqretry(const seqlock_t *sl, unsigned start)
+{
+ return __read_seqcount_retry(&sl->seqcount, start);
+}
+
+/*
* Lock out other writers and update the count.
* Acts like a normal spin_lock/unlock.
* Don't need preempt_disable() because that is in the spin_lock already.
@@ -247,4 +260,55 @@ write_sequnlock_irqrestore(seqlock_t *sl
spin_unlock_irqrestore(&sl->lock, flags);
}
+/*
+ * Instead of open coding a spinlock and a seqcount, the following
+ * functions allow to serialize on the seqlock w/o touching seqcount.
+ */
+static inline void seq_spin_lock(seqlock_t *sl)
+{
+ spin_lock(&sl->lock);
+}
+
+static inline int seq_spin_trylock(seqlock_t *sl)
+{
+ return spin_trylock(&sl->lock);
+}
+
+static inline void seq_spin_unlock(seqlock_t *sl)
+{
+ spin_unlock(&sl->lock);
+}
+
+static inline void assert_seq_spin_locked(seqlock_t *sl)
+{
+ assert_spin_locked(&sl->lock);
+}
+
+static inline void seq_spin_lock_nested(seqlock_t *sl, int subclass)
+{
+ spin_lock_nested(&sl->lock, subclass);
+}
+
+/*
+ * For writers which need to take/release the lock w/o updating seqcount for
+ * whatever reasons the following functions allow to update the count
+ * after the lock has been acquired or before it is released.
+ */
+static inline void write_seqlock_begin(seqlock_t *sl)
+{
+ assert_spin_locked(&sl->lock);
+ write_seqcount_begin(&sl->seqcount);
+}
+
+static inline void write_seqlock_end(seqlock_t *sl)
+{
+ assert_spin_locked(&sl->lock);
+ write_seqcount_end(&sl->seqcount);
+}
+
+static inline void write_seqlock_barrier(seqlock_t *sl)
+{
+ write_seqcount_barrier(&sl->seqcount);
+}
+
#endif /* __LINUX_SEQLOCK_H */

View File

@ -5,7 +5,6 @@
############################################################
# UPSTREAM changes queued for 3.3 or 3.2
############################################################
x88-derandom-tsc-delay-64-bit.patch
x86_64-patch-for-idle-notifiers.patch
re-possible-slab-deadlock-while-doing-ifenslave-1.patch
@ -106,9 +105,12 @@ ia64-vdso-use-seqcount.patch
# SEQLOCK
seqlock-remove-unused-functions.patch
seqlock-use-seqcount.patch
seqlock-provide-seq-spin-lock.patch
fs-struct-use-seqlock.patch
fs-dentry-use-seqlock.patch
#seqlock-provide-seq-spin-lock.patch
#fs-struct-use-seqlock.patch
#fs-dentry-use-seqlock.patch
# VFS. Al Viro provided this so we can deal with the seqcount simpler
vfs-fstruct-move-code-out-of-seqcount-write-sections.patch
# RAW SPINLOCKS
timekeeping-split-xtime-lock.patch
@ -578,8 +580,8 @@ cpumask-disable-offstack-on-rt.patch
# Various fixes - fold them back
seqlock-prevent-rt-starvation.patch
fs-protect-opencoded-isize-seqcount.patch
net-u64-stat-protect-seqcount.patch
#fs-protect-opencoded-isize-seqcount.patch
#net-u64-stat-protect-seqcount.patch
rfc-timer-fix-hotplug-for-rt.patch
rfc-futex-rt-fix-possible-lockup-when-taking-pi_lock-in-proxy-handler.patch
rfc-ring-buffer-rt-check-for-irqs-disabled-before-grabbing-reader-lock.patch
@ -592,7 +594,6 @@ softirq-preempt-fix-3-re.txt
rt-introduce-cpu-chill.patch
fs-dcache-use-cpu-chill-in-trylock-loops.patch
fs-more-cpu-chill-fixups.patch
net-use-cpu-chill.patch
# Enable full RT

View File

@ -1,54 +0,0 @@
From 0bf0d69e1a358e93e5c9b256bb18cab4041e7d8f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
Date: Sun, 11 Mar 2012 17:14:22 +0100
Subject: [PATCH RT] staging/pohmelfs: convert struct fs->lock usage to seq_spin_{,un}lock
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This fixes:
drivers/staging/pohmelfs/path_entry.c:47:2: warning: passing argument 1 of rt_spin_lock from incompatible pointer type [enabled by default]
include/linux/spinlock_rt.h:19:56: note: expected struct spinlock_t * but argument is of type struct seqlock_t *
drivers/staging/pohmelfs/path_entry.c:49:2: warning: passing argument 1 of rt_spin_unlock from incompatible pointer type [enabled by default]
include/linux/spinlock_rt.h:22:56: note: expected struct spinlock_t * but argument is of type struct seqlock_t *
drivers/staging/pohmelfs/path_entry.c:95:2: warning: passing argument 1 of rt_spin_lock from incompatible pointer type [enabled by default]
include/linux/spinlock_rt.h:19:56: note: expected struct spinlock_t * but argument is of type struct seqlock_t *
drivers/staging/pohmelfs/path_entry.c:97:2: warning: passing argument 1 of rt_spin_unlock from incompatible pointer type [enabled by default]
include/linux/spinlock_rt.h:22:56: note: expected struct spinlock_t * but argument is of type struct seqlock_t *
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Forwarded: http://mid.gmane.org/1331482999-32252-1-git-send-email-u.kleine-koenig@pengutronix.de
---
drivers/staging/pohmelfs/path_entry.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/pohmelfs/path_entry.c b/drivers/staging/pohmelfs/path_entry.c
index 400a9fc..fc0c3fe 100644
--- a/drivers/staging/pohmelfs/path_entry.c
+++ b/drivers/staging/pohmelfs/path_entry.c
@@ -44,9 +44,9 @@ int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int le
return -ENOENT;
}
- spin_lock(&current->fs->lock);
+ seq_spin_lock(&current->fs->lock);
path.mnt = mntget(current->fs->root.mnt);
- spin_unlock(&current->fs->lock);
+ seq_spin_unlock(&current->fs->lock);
path.dentry = d;
@@ -92,9 +92,9 @@ int pohmelfs_path_length(struct pohmelfs_inode *pi)
return -ENOENT;
}
- spin_lock(&current->fs->lock);
+ seq_spin_lock(&current->fs->lock);
root = dget(current->fs->root.dentry);
- spin_unlock(&current->fs->lock);
+ seq_spin_unlock(&current->fs->lock);
rename_retry:
len = 1; /* Root slash */

View File

@ -0,0 +1,85 @@
Subject: vfs: fs_struct: Move code out of seqcount write sections
From: Al Viro <viro@ZenIV.linux.org.uk>
Date: Thu, 15 Mar 2012 18:39:40 +0000
RT cannot disable preemption in the seqcount write sections due to
functions called which take "sleeping" spinlocks.
Move the code out of those sections. It does not need to be there.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/fs/fs_struct.c b/fs/fs_struct.c
index 78b519c..f5818c4 100644
--- a/fs/fs_struct.c
+++ b/fs/fs_struct.c
@@ -26,11 +26,11 @@ void set_fs_root(struct fs_struct *fs, struct path *path)
{
struct path old_root;
+ path_get_longterm(path);
spin_lock(&fs->lock);
write_seqcount_begin(&fs->seq);
old_root = fs->root;
fs->root = *path;
- path_get_longterm(path);
write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock);
if (old_root.dentry)
@@ -45,11 +45,11 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path)
{
struct path old_pwd;
+ path_get_longterm(path);
spin_lock(&fs->lock);
write_seqcount_begin(&fs->seq);
old_pwd = fs->pwd;
fs->pwd = *path;
- path_get_longterm(path);
write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock);
@@ -57,6 +57,14 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path)
path_put_longterm(&old_pwd);
}
+static inline int replace_path(struct path *p, const struct path *old, const struct path *new)
+{
+ if (likely(p->dentry != old->dentry || p->mnt != old->mnt))
+ return 0;
+ *p = *new;
+ return 1;
+}
+
void chroot_fs_refs(struct path *old_root, struct path *new_root)
{
struct task_struct *g, *p;
@@ -68,21 +76,16 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root)
task_lock(p);
fs = p->fs;
if (fs) {
+ int hits = 0;
spin_lock(&fs->lock);
write_seqcount_begin(&fs->seq);
- if (fs->root.dentry == old_root->dentry
- && fs->root.mnt == old_root->mnt) {
- path_get_longterm(new_root);
- fs->root = *new_root;
+ hits += replace_path(&fs->root, old_root, new_root);
+ hits += replace_path(&fs->pwd, old_root, new_root);
+ write_seqcount_end(&fs->seq);
+ while (hits--) {
count++;
- }
- if (fs->pwd.dentry == old_root->dentry
- && fs->pwd.mnt == old_root->mnt) {
path_get_longterm(new_root);
- fs->pwd = *new_root;
- count++;
}
- write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock);
}
task_unlock(p);

View File

@ -18,9 +18,7 @@
+ features/all/rt/ia64-vdso-use-seqcount.patch featureset=rt
+ features/all/rt/seqlock-remove-unused-functions.patch featureset=rt
+ features/all/rt/seqlock-use-seqcount.patch featureset=rt
+ features/all/rt/seqlock-provide-seq-spin-lock.patch featureset=rt
+ features/all/rt/fs-struct-use-seqlock.patch featureset=rt
+ features/all/rt/fs-dentry-use-seqlock.patch featureset=rt
+ features/all/rt/vfs-fstruct-move-code-out-of-seqcount-write-sections.patch featureset=rt
+ features/all/rt/timekeeping-split-xtime-lock.patch featureset=rt
+ features/all/rt/intel_idle-convert-i7300_idle_lock-to-raw-spinlock.patch featureset=rt
+ features/all/rt/mm-memcg-shorten-preempt-disabled-section-around-event-checks.patch featureset=rt
@ -252,8 +250,6 @@
+ features/all/rt/dm-make-rt-aware.patch featureset=rt
+ features/all/rt/cpumask-disable-offstack-on-rt.patch featureset=rt
+ features/all/rt/seqlock-prevent-rt-starvation.patch featureset=rt
+ features/all/rt/fs-protect-opencoded-isize-seqcount.patch featureset=rt
+ features/all/rt/net-u64-stat-protect-seqcount.patch featureset=rt
+ features/all/rt/rfc-timer-fix-hotplug-for-rt.patch featureset=rt
+ features/all/rt/rfc-futex-rt-fix-possible-lockup-when-taking-pi_lock-in-proxy-handler.patch featureset=rt
+ features/all/rt/rfc-ring-buffer-rt-check-for-irqs-disabled-before-grabbing-reader-lock.patch featureset=rt
@ -263,9 +259,6 @@
+ features/all/rt/softirq-preempt-fix-3-re.txt featureset=rt
+ features/all/rt/rt-introduce-cpu-chill.patch featureset=rt
+ features/all/rt/fs-dcache-use-cpu-chill-in-trylock-loops.patch featureset=rt
+ features/all/rt/fs-more-cpu-chill-fixups.patch featureset=rt
+ features/all/rt/net-use-cpu-chill.patch featureset=rt
+ features/all/rt/kconfig-disable-a-few-options-rt.patch featureset=rt
+ features/all/rt/kconfig-preempt-rt-full.patch featureset=rt
+ features/all/rt/fix-rt+link-creation-restrictions featureset=rt
+ features/all/rt/staging-pohmelfs-convert-struct-fs-lock-usage-to-.patch featureset=rt