Dear RT Folks, I'm pleased to announce the 3.0.23-rt40 stable release. You can get this release via the git tree at: git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-stable-rt.git Head SHA1: 1a71c9ae0f844238de43681c41563a4203b7e933 Or to build 3.0.23-rt40 directly, the following patches should be applied: http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.0.tar.xz http://www.kernel.org/pub/linux/kernel/v3.0/patch-3.0.23.xz http://www.kernel.org/pub/linux/kernel/projects/rt/3.0/patch-3.0.23-rt40.patch.xz You can also build from 3.0.23-rt39 by applying the incremental patch: http://www.kernel.org/pub/linux/kernel/projects/rt/3.0/incr/patch-3.0.23-rt39-rt40.patch.xz Enjoy, -- Steve Changes from 3.0.23-rt39: --- Steven Rostedt (2): Revert "ACPI: Convert embedded controller lock to raw spinlock" Linux 3.0.23-rt40 Thomas Gleixner (5): softirq: Check preemption after reenabling interrupts rt: Introduce cpu_chill() fs: dcache: Use cpu_chill() in trylock loops fs: namespace: Use cpu_chill() instead of cpu_relax() net: Use cpu_chill() instead of cpu_relax() ---- block/blk-iopoll.c | 3 +++ block/blk-softirq.c | 3 +++ drivers/acpi/ec.c | 22 +++++++++++----------- drivers/acpi/internal.h | 2 +- fs/autofs4/autofs_i.h | 1 + fs/autofs4/expire.c | 2 +- fs/dcache.c | 7 ++++--- fs/namespace.c | 3 ++- include/linux/delay.h | 6 ++++++ include/linux/preempt.h | 3 +++ localversion-rt | 2 +- net/core/dev.c | 6 ++++++ net/rds/ib_rdma.c | 3 ++- 13 files changed, 44 insertions(+), 19 deletions(-) --------------------------- diff --git a/block/blk-iopoll.c b/block/blk-iopoll.c index 58916af..f7ca9b4 100644 --- a/block/blk-iopoll.c +++ b/block/blk-iopoll.c @@ -38,6 +38,7 @@ void blk_iopoll_sched(struct blk_iopoll *iop) list_add_tail(&iop->list, &__get_cpu_var(blk_cpu_iopoll)); __raise_softirq_irqoff(BLOCK_IOPOLL_SOFTIRQ); local_irq_restore(flags); + preempt_check_resched_rt(); } EXPORT_SYMBOL(blk_iopoll_sched); @@ -135,6 +136,7 @@ static void blk_iopoll_softirq(struct softirq_action *h) __raise_softirq_irqoff(BLOCK_IOPOLL_SOFTIRQ); local_irq_enable(); + preempt_check_resched_rt(); } /** @@ -204,6 +206,7 @@ static int __cpuinit blk_iopoll_cpu_notify(struct notifier_block *self, &__get_cpu_var(blk_cpu_iopoll)); __raise_softirq_irqoff(BLOCK_IOPOLL_SOFTIRQ); local_irq_enable(); + preempt_check_resched_rt(); } return NOTIFY_OK; diff --git a/block/blk-softirq.c b/block/blk-softirq.c index ee9c216..0206963 100644 --- a/block/blk-softirq.c +++ b/block/blk-softirq.c @@ -50,6 +50,7 @@ static void trigger_softirq(void *data) raise_softirq_irqoff(BLOCK_SOFTIRQ); local_irq_restore(flags); + preempt_check_resched_rt(); } /* @@ -92,6 +93,7 @@ static int __cpuinit blk_cpu_notify(struct notifier_block *self, &__get_cpu_var(blk_cpu_done)); raise_softirq_irqoff(BLOCK_SOFTIRQ); local_irq_enable(); + preempt_check_resched_rt(); } return NOTIFY_OK; @@ -139,6 +141,7 @@ do_local: goto do_local; local_irq_restore(flags); + preempt_check_resched_rt(); } /** diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index db0e6c3..b72a603 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -152,10 +152,10 @@ static int ec_transaction_done(struct acpi_ec *ec) { unsigned long flags; int ret = 0; - raw_spin_lock_irqsave(&ec->curr_lock, flags); + spin_lock_irqsave(&ec->curr_lock, flags); if (!ec->curr || ec->curr->done) ret = 1; - raw_spin_unlock_irqrestore(&ec->curr_lock, flags); + spin_unlock_irqrestore(&ec->curr_lock, flags); return ret; } @@ -169,7 +169,7 @@ static void start_transaction(struct acpi_ec *ec) static void advance_transaction(struct acpi_ec *ec, u8 status) { unsigned long flags; - raw_spin_lock_irqsave(&ec->curr_lock, flags); + spin_lock_irqsave(&ec->curr_lock, flags); if (!ec->curr) goto unlock; if (ec->curr->wlen > ec->curr->wi) { @@ -194,7 +194,7 @@ err: if (in_interrupt()) ++ec->curr->irq_count; unlock: - raw_spin_unlock_irqrestore(&ec->curr_lock, flags); + spin_unlock_irqrestore(&ec->curr_lock, flags); } static int acpi_ec_sync_query(struct acpi_ec *ec); @@ -232,9 +232,9 @@ static int ec_poll(struct acpi_ec *ec) if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) break; pr_debug(PREFIX "controller reset, restart transaction\n"); - raw_spin_lock_irqsave(&ec->curr_lock, flags); + spin_lock_irqsave(&ec->curr_lock, flags); start_transaction(ec); - raw_spin_unlock_irqrestore(&ec->curr_lock, flags); + spin_unlock_irqrestore(&ec->curr_lock, flags); } return -ETIME; } @@ -247,17 +247,17 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, if (EC_FLAGS_MSI) udelay(ACPI_EC_MSI_UDELAY); /* start transaction */ - raw_spin_lock_irqsave(&ec->curr_lock, tmp); + spin_lock_irqsave(&ec->curr_lock, tmp); /* following two actions should be kept atomic */ ec->curr = t; start_transaction(ec); if (ec->curr->command == ACPI_EC_COMMAND_QUERY) clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); - raw_spin_unlock_irqrestore(&ec->curr_lock, tmp); + spin_unlock_irqrestore(&ec->curr_lock, tmp); ret = ec_poll(ec); - raw_spin_lock_irqsave(&ec->curr_lock, tmp); + spin_lock_irqsave(&ec->curr_lock, tmp); ec->curr = NULL; - raw_spin_unlock_irqrestore(&ec->curr_lock, tmp); + spin_unlock_irqrestore(&ec->curr_lock, tmp); return ret; } @@ -678,7 +678,7 @@ static struct acpi_ec *make_acpi_ec(void) mutex_init(&ec->lock); init_swait_head(&ec->wait); INIT_LIST_HEAD(&ec->list); - raw_spin_lock_init(&ec->curr_lock); + spin_lock_init(&ec->curr_lock); return ec; } diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 2519b6e..6f889ba 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -64,7 +64,7 @@ struct acpi_ec { struct swait_head wait; struct list_head list; struct transaction *curr; - raw_spinlock_t curr_lock; + spinlock_t curr_lock; }; extern struct acpi_ec *first_ec; diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index b620114..83424ab 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h @@ -34,6 +34,7 @@ #include <linux/sched.h> #include <linux/mount.h> #include <linux/namei.h> +#include <linux/delay.h> #include <asm/current.h> #include <asm/uaccess.h> diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index d8b6184..f4abda3 100644 --- a/fs/autofs4/expire.c +++ b/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); - cpu_relax(); + cpu_chill(); goto relock; } seq_spin_unlock(&p->d_lock); diff --git a/fs/dcache.c b/fs/dcache.c index 10580be..eedf276 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -36,6 +36,7 @@ #include <linux/bit_spinlock.h> #include <linux/rculist_bl.h> #include <linux/prefetch.h> +#include <linux/delay.h> #include "internal.h" /* @@ -360,7 +361,7 @@ static inline struct dentry *dentry_kill(struct dentry *dentry, int ref) if (inode && !spin_trylock(&inode->i_lock)) { relock: seq_spin_unlock(&dentry->d_lock); - cpu_relax(); + cpu_chill(); return dentry; /* try again with same dentry */ } if (IS_ROOT(dentry)) @@ -738,7 +739,7 @@ relock: if (!seq_spin_trylock(&dentry->d_lock)) { spin_unlock(&dcache_lru_lock); - cpu_relax(); + cpu_chill(); goto relock; } @@ -2053,7 +2054,7 @@ again: if (dentry->d_count == 1) { if (inode && !spin_trylock(&inode->i_lock)) { seq_spin_unlock(&dentry->d_lock); - cpu_relax(); + cpu_chill(); goto again; } dentry->d_flags &= ~DCACHE_CANT_MOUNT; diff --git a/fs/namespace.c b/fs/namespace.c index c563781..3270cde 100644 --- a/fs/namespace.c +++ b/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(); } /* diff --git a/include/linux/delay.h b/include/linux/delay.h index a6ecb34..e23a7c0 100644 --- a/include/linux/delay.h +++ b/include/linux/delay.h @@ -52,4 +52,10 @@ static inline void ssleep(unsigned int seconds) msleep(seconds * 1000); } +#ifdef CONFIG_PREEMPT_RT_FULL +# define cpu_chill() msleep(1) +#else +# define cpu_chill() cpu_relax() +#endif + #endif /* defined(_LINUX_DELAY_H) */ diff --git a/include/linux/preempt.h b/include/linux/preempt.h index 7a2bbbb..11412d7 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -41,8 +41,10 @@ do { \ #ifndef CONFIG_PREEMPT_RT_BASE # define preempt_enable_no_resched() __preempt_enable_no_resched() +# define preempt_check_resched_rt() do { } while (0) #else # define preempt_enable_no_resched() preempt_enable() +# define preempt_check_resched_rt() preempt_check_resched() #endif #define preempt_check_resched() \ @@ -93,6 +95,7 @@ do { \ #define preempt_enable_no_resched() do { } while (0) #define preempt_enable() do { } while (0) #define preempt_check_resched() do { } while (0) +#define preempt_check_resched_rt() do { } while (0) #define preempt_disable_notrace() do { } while (0) #define preempt_enable_no_resched_notrace() do { } while (0) diff --git a/localversion-rt b/localversion-rt index 5498386..2af6c89 100644 --- a/localversion-rt +++ b/localversion-rt @@ -1 +1 @@ --rt39 +-rt40 diff --git a/net/core/dev.c b/net/core/dev.c index 7606d18..b250c1d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1705,6 +1705,7 @@ static inline void __netif_reschedule(struct Qdisc *q) sd->output_queue_tailp = &q->next_sched; raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_restore(flags); + preempt_check_resched_rt(); } void __netif_schedule(struct Qdisc *q) @@ -1726,6 +1727,7 @@ void dev_kfree_skb_irq(struct sk_buff *skb) sd->completion_queue = skb; raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_restore(flags); + preempt_check_resched_rt(); } } EXPORT_SYMBOL(dev_kfree_skb_irq); @@ -2837,6 +2839,7 @@ enqueue: rps_unlock(sd); local_irq_restore(flags); + preempt_check_resched_rt(); atomic_long_inc(&skb->dev->rx_dropped); kfree_skb(skb); @@ -3659,6 +3662,7 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd) } else #endif local_irq_enable(); + preempt_check_resched_rt(); } static int process_backlog(struct napi_struct *napi, int quota) @@ -3731,6 +3735,7 @@ void __napi_schedule(struct napi_struct *n) local_irq_save(flags); ____napi_schedule(&__get_cpu_var(softnet_data), n); local_irq_restore(flags); + preempt_check_resched_rt(); } EXPORT_SYMBOL(__napi_schedule); @@ -6233,6 +6238,7 @@ static int dev_cpu_callback(struct notifier_block *nfb, raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_enable(); + preempt_check_resched_rt(); /* Process offline CPU's input_pkt_queue */ while ((skb = __skb_dequeue(&oldsd->process_queue))) { diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 819c35a..256ad87 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -33,6 +33,7 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/rculist.h> +#include <linux/delay.h> #include "rds.h" #include "ib.h" @@ -294,7 +295,7 @@ static inline void wait_clean_list_grace(void) for_each_online_cpu(cpu) { flag = &per_cpu(clean_list_grace, cpu); while (test_bit(CLEAN_LIST_BUSY_BIT, flag)) - cpu_relax(); + cpu_chill(); } }
Attachment:
signature.asc
Description: This is a digitally signed message part