Linux v3.7.3

This commit is contained in:
Josh Boyer 2013-01-17 21:28:24 -05:00
parent 8e4071a187
commit bf8beb2520
46 changed files with 267 additions and 4922 deletions

View File

@ -1,50 +0,0 @@
From 690b1ad9d2032d6f2565d44f6564590d47835ae8 Mon Sep 17 00:00:00 2001
From: Zhang Rui <rui.zhang@intel.com>
Date: Thu, 29 Nov 2012 01:30:43 +0800
Subject: [PATCH 1/2] ACPI sony-laptop: do proper memcpy for ACPI_TYPE_INTEGER
acpi_object
the return value of __call_snc_method can either be
an ACPI_TYPE_BUFFER object or a ACPI_TYPE_INTEGER object.
do proper memcpy for ACPI_TYPE_INTEGER object.
https://bugzilla.kernel.org/show_bug.cgi?id=50111
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
drivers/platform/x86/sony-laptop.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index daaddec..92e0da2 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -792,20 +792,19 @@ static int sony_nc_buffer_call(acpi_handle handle, char *name, u64 *value,
if (!object)
return -EINVAL;
- if (object->type == ACPI_TYPE_BUFFER)
+ if (object->type == ACPI_TYPE_BUFFER) {
len = MIN(buflen, object->buffer.length);
-
- else if (object->type == ACPI_TYPE_INTEGER)
+ memcpy(buffer, object->buffer.pointer, len);
+ } else if (object->type == ACPI_TYPE_INTEGER) {
len = MIN(buflen, sizeof(object->integer.value));
-
- else {
+ memcpy(buffer, (void *)&object->integer.value, len);
+ } else {
pr_warn("Invalid acpi_object: expected 0x%x got 0x%x\n",
ACPI_TYPE_BUFFER, object->type);
kfree(object);
return -EINVAL;
}
- memcpy(buffer, object->buffer.pointer, len);
kfree(object);
return 0;
}
--
1.7.9.5

View File

@ -1,121 +0,0 @@
From 50b61634cf8d09f9ef334919b859735d381cbe39 Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <dmonakhov@openvz.org>
Date: Fri, 28 Sep 2012 23:21:09 -0400
Subject: [PATCH 01/13] ext4: ext4_inode_info diet
Generic inode has unused i_private pointer which may be used as cur_aio_dio
storage.
TODO: If cur_aio_dio will be passed as an argument to get_block_t this allow
to have concurent AIO_DIO requests.
Reviewed-by: Zheng Liu <wenqing.lz@taobao.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit f45ee3a1ea438af96e4fd2c0b16d195e67ef235f)
---
fs/ext4/ext4.h | 12 ++++++++++--
fs/ext4/extents.c | 4 ++--
fs/ext4/inode.c | 6 +++---
fs/ext4/super.c | 1 -
4 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index c3411d4..80afc8f 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -912,8 +912,6 @@ struct ext4_inode_info {
struct list_head i_completed_io_list;
spinlock_t i_completed_io_lock;
atomic_t i_ioend_count; /* Number of outstanding io_end structs */
- /* current io_end structure for async DIO write*/
- ext4_io_end_t *cur_aio_dio;
atomic_t i_aiodio_unwritten; /* Nr. of inflight conversions pending */
spinlock_t i_block_reservation_lock;
@@ -1332,6 +1330,16 @@ static inline void ext4_set_io_unwritten_flag(struct inode *inode,
}
}
+static inline ext4_io_end_t *ext4_inode_aio(struct inode *inode)
+{
+ return inode->i_private;
+}
+
+static inline void ext4_inode_aio_set(struct inode *inode, ext4_io_end_t *io)
+{
+ inode->i_private = io;
+}
+
/*
* Inode dynamic state flags
*/
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index aabbb3f..51fbef1 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -3600,7 +3600,7 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
{
int ret = 0;
int err = 0;
- ext4_io_end_t *io = EXT4_I(inode)->cur_aio_dio;
+ ext4_io_end_t *io = ext4_inode_aio(inode);
ext_debug("ext4_ext_handle_uninitialized_extents: inode %lu, logical "
"block %llu, max_blocks %u, flags %x, allocated %u\n",
@@ -3858,7 +3858,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
unsigned int allocated = 0, offset = 0;
unsigned int allocated_clusters = 0;
struct ext4_allocation_request ar;
- ext4_io_end_t *io = EXT4_I(inode)->cur_aio_dio;
+ ext4_io_end_t *io = ext4_inode_aio(inode);
ext4_lblk_t cluster_offset;
ext_debug("blocks %u/%u requested for inode %lu\n",
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index dff171c..acadd2b 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3054,7 +3054,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
* hook to the iocb.
*/
iocb->private = NULL;
- EXT4_I(inode)->cur_aio_dio = NULL;
+ ext4_inode_aio_set(inode, NULL);
if (!is_sync_kiocb(iocb)) {
ext4_io_end_t *io_end =
ext4_init_io_end(inode, GFP_NOFS);
@@ -3071,7 +3071,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
* is a unwritten extents needs to be converted
* when IO is completed.
*/
- EXT4_I(inode)->cur_aio_dio = iocb->private;
+ ext4_inode_aio_set(inode, io_end);
}
if (overwrite)
@@ -3091,7 +3091,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
NULL,
DIO_LOCKING);
if (iocb->private)
- EXT4_I(inode)->cur_aio_dio = NULL;
+ ext4_inode_aio_set(inode, NULL);
/*
* The io_end structure takes a reference to the inode,
* that structure needs to be destroyed and the
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index c6e0cb3..270e58f 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -956,7 +956,6 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
ei->jinode = NULL;
INIT_LIST_HEAD(&ei->i_completed_io_list);
spin_lock_init(&ei->i_completed_io_lock);
- ei->cur_aio_dio = NULL;
ei->i_sync_tid = 0;
ei->i_datasync_tid = 0;
atomic_set(&ei->i_ioend_count, 0);
--
1.7.12.rc0.22.gcdd159b

View File

@ -1,97 +0,0 @@
From 027d1aa67e32c2c80851105c6d962f3db46eb476 Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <dmonakhov@openvz.org>
Date: Fri, 28 Sep 2012 23:24:52 -0400
Subject: [PATCH 02/13] ext4: give i_aiodio_unwritten a more appropriate name
AIO/DIO prefix is wrong because it account unwritten extents which
also may be scheduled from buffered write endio
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit e27f41e1b789e60e7d8cc9c81fd93ca49ef31f13)
---
fs/ext4/ext4.h | 4 ++--
fs/ext4/file.c | 6 +++---
fs/ext4/page-io.c | 2 +-
fs/ext4/super.c | 2 +-
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 80afc8f..28dfd9b 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -912,7 +912,7 @@ struct ext4_inode_info {
struct list_head i_completed_io_list;
spinlock_t i_completed_io_lock;
atomic_t i_ioend_count; /* Number of outstanding io_end structs */
- atomic_t i_aiodio_unwritten; /* Nr. of inflight conversions pending */
+ atomic_t i_unwritten; /* Nr. of inflight conversions pending */
spinlock_t i_block_reservation_lock;
@@ -1326,7 +1326,7 @@ static inline void ext4_set_io_unwritten_flag(struct inode *inode,
{
if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) {
io_end->flag |= EXT4_IO_END_UNWRITTEN;
- atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten);
+ atomic_inc(&EXT4_I(inode)->i_unwritten);
}
}
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 3b0e3bd..39335bd 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -55,11 +55,11 @@ static int ext4_release_file(struct inode *inode, struct file *filp)
return 0;
}
-static void ext4_aiodio_wait(struct inode *inode)
+static void ext4_unwritten_wait(struct inode *inode)
{
wait_queue_head_t *wq = ext4_ioend_wq(inode);
- wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_aiodio_unwritten) == 0));
+ wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_unwritten) == 0));
}
/*
@@ -116,7 +116,7 @@ ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov,
"performance will be poor.",
inode->i_ino, current->comm);
mutex_lock(ext4_aio_mutex(inode));
- ext4_aiodio_wait(inode);
+ ext4_unwritten_wait(inode);
}
BUG_ON(iocb->ki_pos != pos);
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index dcdeef1..de77e31 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -113,7 +113,7 @@ int ext4_end_io_nolock(ext4_io_end_t *io)
if (io->flag & EXT4_IO_END_DIRECT)
inode_dio_done(inode);
/* Wake up anyone waiting on unwritten extent conversion */
- if (atomic_dec_and_test(&EXT4_I(inode)->i_aiodio_unwritten))
+ if (atomic_dec_and_test(&EXT4_I(inode)->i_unwritten))
wake_up_all(ext4_ioend_wq(io->inode));
return ret;
}
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 270e58f..1b6b425 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -959,7 +959,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
ei->i_sync_tid = 0;
ei->i_datasync_tid = 0;
atomic_set(&ei->i_ioend_count, 0);
- atomic_set(&ei->i_aiodio_unwritten, 0);
+ atomic_set(&ei->i_unwritten, 0);
return &ei->vfs_inode;
}
--
1.7.12.rc0.22.gcdd159b

View File

@ -1,112 +0,0 @@
From 6a0e905bb7320571ed5fdd2d5efa3d642630b4f7 Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <dmonakhov@openvz.org>
Date: Fri, 28 Sep 2012 23:36:25 -0400
Subject: [PATCH 03/13] ext4: fix unwritten counter leakage
ext4_set_io_unwritten_flag() will increment i_unwritten counter, so
once we mark end_io with EXT4_END_IO_UNWRITTEN we have to revert it back
on error path.
- add missed error checks to prevent counter leakage
- ext4_end_io_nolock() will clear EXT4_END_IO_UNWRITTEN flag to signal
that conversion finished.
- add BUG_ON to ext4_free_end_io() to prevent similar leakage in future.
Visible effect of this bug is that unaligned aio_stress may deadlock
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 82e54229118785badffb4ef5ba4803df25fe007f)
---
fs/ext4/extents.c | 21 ++++++++++++++-------
fs/ext4/page-io.c | 6 +++++-
2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 51fbef1..e04eb4f 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -3615,6 +3615,8 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
if ((flags & EXT4_GET_BLOCKS_PRE_IO)) {
ret = ext4_split_unwritten_extents(handle, inode, map,
path, flags);
+ if (ret <= 0)
+ goto out;
/*
* Flag the inode(non aio case) or end_io struct (aio case)
* that this IO needs to conversion to written when IO is
@@ -3860,6 +3862,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
struct ext4_allocation_request ar;
ext4_io_end_t *io = ext4_inode_aio(inode);
ext4_lblk_t cluster_offset;
+ int set_unwritten = 0;
ext_debug("blocks %u/%u requested for inode %lu\n",
map->m_lblk, map->m_len, inode->i_ino);
@@ -4082,13 +4085,8 @@ got_allocated_blocks:
* For non asycn direct IO case, flag the inode state
* that we need to perform conversion when IO is done.
*/
- if ((flags & EXT4_GET_BLOCKS_PRE_IO)) {
- if (io)
- ext4_set_io_unwritten_flag(inode, io);
- else
- ext4_set_inode_state(inode,
- EXT4_STATE_DIO_UNWRITTEN);
- }
+ if ((flags & EXT4_GET_BLOCKS_PRE_IO))
+ set_unwritten = 1;
if (ext4_should_dioread_nolock(inode))
map->m_flags |= EXT4_MAP_UNINIT;
}
@@ -4100,6 +4098,15 @@ got_allocated_blocks:
if (!err)
err = ext4_ext_insert_extent(handle, inode, path,
&newex, flags);
+
+ if (!err && set_unwritten) {
+ if (io)
+ ext4_set_io_unwritten_flag(inode, io);
+ else
+ ext4_set_inode_state(inode,
+ EXT4_STATE_DIO_UNWRITTEN);
+ }
+
if (err && free_on_err) {
int fb_flags = flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE ?
EXT4_FREE_BLOCKS_NO_QUOT_UPDATE : 0;
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index de77e31..9970022 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -71,6 +71,8 @@ void ext4_free_io_end(ext4_io_end_t *io)
int i;
BUG_ON(!io);
+ BUG_ON(io->flag & EXT4_IO_END_UNWRITTEN);
+
if (io->page)
put_page(io->page);
for (i = 0; i < io->num_io_pages; i++)
@@ -94,6 +96,8 @@ int ext4_end_io_nolock(ext4_io_end_t *io)
ssize_t size = io->size;
int ret = 0;
+ BUG_ON(!(io->flag & EXT4_IO_END_UNWRITTEN));
+
ext4_debug("ext4_end_io_nolock: io 0x%p from inode %lu,list->next 0x%p,"
"list->prev 0x%p\n",
io, inode->i_ino, io->list.next, io->list.prev);
@@ -106,7 +110,7 @@ int ext4_end_io_nolock(ext4_io_end_t *io)
"(inode %lu, offset %llu, size %zd, error %d)",
inode->i_ino, offset, size, ret);
}
-
+ io->flag &= ~EXT4_IO_END_UNWRITTEN;
if (io->iocb)
aio_complete(io->iocb, io->result, 0);
--
1.7.12.rc0.22.gcdd159b

View File

@ -1,520 +0,0 @@
From e23394806df0768ed2dac87484590d2f3a730d55 Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <dmonakhov@openvz.org>
Date: Sat, 29 Sep 2012 00:14:55 -0400
Subject: [PATCH 04/13] ext4: completed_io locking cleanup
Current unwritten extent conversion state-machine is very fuzzy.
- For unknown reason it performs conversion under i_mutex. What for?
My diagnosis:
We already protect extent tree with i_data_sem, truncate and punch_hole
should wait for DIO, so the only data we have to protect is end_io->flags
modification, but only flush_completed_IO and end_io_work modified this
flags and we can serialize them via i_completed_io_lock.
Currently all these games with mutex_trylock result in the following deadlock
truncate: kworker:
ext4_setattr ext4_end_io_work
mutex_lock(i_mutex)
inode_dio_wait(inode) ->BLOCK
DEADLOCK<- mutex_trylock()
inode_dio_done()
#TEST_CASE1_BEGIN
MNT=/mnt_scrach
unlink $MNT/file
fallocate -l $((1024*1024*1024)) $MNT/file
aio-stress -I 100000 -O -s 100m -n -t 1 -c 10 -o 2 -o 3 $MNT/file
sleep 2
truncate -s 0 $MNT/file
#TEST_CASE1_END
Or use 286's xfstests https://github.com/dmonakhov/xfstests/blob/devel/286
This patch makes state machine simple and clean:
(1) xxx_end_io schedule final extent conversion simply by calling
ext4_add_complete_io(), which append it to ei->i_completed_io_list
NOTE1: because of (2A) work should be queued only if
->i_completed_io_list was empty, otherwise the work is scheduled already.
(2) ext4_flush_completed_IO is responsible for handling all pending
end_io from ei->i_completed_io_list
Flushing sequence consists of following stages:
A) LOCKED: Atomically drain completed_io_list to local_list
B) Perform extents conversion
C) LOCKED: move converted io's to to_free list for final deletion
This logic depends on context which we was called from.
D) Final end_io context destruction
NOTE1: i_mutex is no longer required because end_io->flags modification
is protected by ei->ext4_complete_io_lock
Full list of changes:
- Move all completion end_io related routines to page-io.c in order to improve
logic locality
- Move open coded logic from various xx_end_xx routines to ext4_add_complete_io()
- remove EXT4_IO_END_FSYNC
- Improve SMP scalability by removing useless i_mutex which does not
protect io->flags anymore.
- Reduce lock contention on i_completed_io_lock by optimizing list walk.
- Rename ext4_end_io_nolock to end4_end_io and make it static
- Check flush completion status to ext4_ext_punch_hole(). Because it is
not good idea to punch blocks from corrupted inode.
Changes since V3 (in request to Jan's comments):
Fall back to active flush_completed_IO() approach in order to prevent
performance issues with nolocked DIO reads.
Changes since V2:
Fix use-after-free caused by race truncate vs end_io_work
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 28a535f9a0df060569dcc786e5bc2e1de43d7dc7)
---
fs/ext4/ext4.h | 3 +-
fs/ext4/extents.c | 4 +-
fs/ext4/fsync.c | 81 -------------------------
fs/ext4/indirect.c | 6 +-
fs/ext4/inode.c | 25 +-------
fs/ext4/page-io.c | 171 +++++++++++++++++++++++++++++++++++------------------
6 files changed, 121 insertions(+), 169 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 28dfd9b..7687d15 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -186,7 +186,6 @@ struct mpage_da_data {
#define EXT4_IO_END_ERROR 0x0002
#define EXT4_IO_END_QUEUED 0x0004
#define EXT4_IO_END_DIRECT 0x0008
-#define EXT4_IO_END_IN_FSYNC 0x0010
struct ext4_io_page {
struct page *p_page;
@@ -2408,11 +2407,11 @@ extern int ext4_move_extents(struct file *o_filp, struct file *d_filp,
/* page-io.c */
extern int __init ext4_init_pageio(void);
+extern void ext4_add_complete_io(ext4_io_end_t *io_end);
extern void ext4_exit_pageio(void);
extern void ext4_ioend_wait(struct inode *);
extern void ext4_free_io_end(ext4_io_end_t *io);
extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags);
-extern int ext4_end_io_nolock(ext4_io_end_t *io);
extern void ext4_io_submit(struct ext4_io_submit *io);
extern int ext4_bio_write_page(struct ext4_io_submit *io,
struct page *page,
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index e04eb4f..1fbf2ff 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4815,7 +4815,9 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
}
/* finish any pending end_io work */
- ext4_flush_completed_IO(inode);
+ err = ext4_flush_completed_IO(inode);
+ if (err)
+ return err;
credits = ext4_writepage_trans_blocks(inode);
handle = ext4_journal_start(inode, credits);
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
index 2a1dcea..520b058 100644
--- a/fs/ext4/fsync.c
+++ b/fs/ext4/fsync.c
@@ -34,87 +34,6 @@
#include <trace/events/ext4.h>
-static void dump_completed_IO(struct inode * inode)
-{
-#ifdef EXT4FS_DEBUG
- struct list_head *cur, *before, *after;
- ext4_io_end_t *io, *io0, *io1;
- unsigned long flags;
-
- if (list_empty(&EXT4_I(inode)->i_completed_io_list)){
- ext4_debug("inode %lu completed_io list is empty\n", inode->i_ino);
- return;
- }
-
- ext4_debug("Dump inode %lu completed_io list \n", inode->i_ino);
- spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
- list_for_each_entry(io, &EXT4_I(inode)->i_completed_io_list, list){
- cur = &io->list;
- before = cur->prev;
- io0 = container_of(before, ext4_io_end_t, list);
- after = cur->next;
- io1 = container_of(after, ext4_io_end_t, list);
-
- ext4_debug("io 0x%p from inode %lu,prev 0x%p,next 0x%p\n",
- io, inode->i_ino, io0, io1);
- }
- spin_unlock_irqrestore(&EXT4_I(inode)->i_completed_io_lock, flags);
-#endif
-}
-
-/*
- * This function is called from ext4_sync_file().
- *
- * When IO is completed, the work to convert unwritten extents to
- * written is queued on workqueue but may not get immediately
- * scheduled. When fsync is called, we need to ensure the
- * conversion is complete before fsync returns.
- * The inode keeps track of a list of pending/completed IO that
- * might needs to do the conversion. This function walks through
- * the list and convert the related unwritten extents for completed IO
- * to written.
- * The function return the number of pending IOs on success.
- */
-int ext4_flush_completed_IO(struct inode *inode)
-{
- ext4_io_end_t *io;
- struct ext4_inode_info *ei = EXT4_I(inode);
- unsigned long flags;
- int ret = 0;
- int ret2 = 0;
-
- dump_completed_IO(inode);
- spin_lock_irqsave(&ei->i_completed_io_lock, flags);
- while (!list_empty(&ei->i_completed_io_list)){
- io = list_entry(ei->i_completed_io_list.next,
- ext4_io_end_t, list);
- list_del_init(&io->list);
- io->flag |= EXT4_IO_END_IN_FSYNC;
- /*
- * Calling ext4_end_io_nolock() to convert completed
- * IO to written.
- *
- * When ext4_sync_file() is called, run_queue() may already
- * about to flush the work corresponding to this io structure.
- * It will be upset if it founds the io structure related
- * to the work-to-be schedule is freed.
- *
- * Thus we need to keep the io structure still valid here after
- * conversion finished. The io structure has a flag to
- * avoid double converting from both fsync and background work
- * queue work.
- */
- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
- ret = ext4_end_io_nolock(io);
- if (ret < 0)
- ret2 = ret;
- spin_lock_irqsave(&ei->i_completed_io_lock, flags);
- io->flag &= ~EXT4_IO_END_IN_FSYNC;
- }
- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
- return (ret2 < 0) ? ret2 : 0;
-}
-
/*
* If we're not journaling and this is a just-created file, we have to
* sync our parent directory (if it was freshly created) since
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
index 830e1b2..61f13e5 100644
--- a/fs/ext4/indirect.c
+++ b/fs/ext4/indirect.c
@@ -807,11 +807,9 @@ ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
retry:
if (rw == READ && ext4_should_dioread_nolock(inode)) {
- if (unlikely(!list_empty(&ei->i_completed_io_list))) {
- mutex_lock(&inode->i_mutex);
+ if (unlikely(!list_empty(&ei->i_completed_io_list)))
ext4_flush_completed_IO(inode);
- mutex_unlock(&inode->i_mutex);
- }
+
ret = __blockdev_direct_IO(rw, iocb, inode,
inode->i_sb->s_bdev, iov,
offset, nr_segs,
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index acadd2b..dd3fd23 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2879,9 +2879,6 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
{
struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
ext4_io_end_t *io_end = iocb->private;
- struct workqueue_struct *wq;
- unsigned long flags;
- struct ext4_inode_info *ei;
/* if not async direct IO or dio with 0 bytes write, just return */
if (!io_end || !size)
@@ -2910,24 +2907,14 @@ out:
io_end->iocb = iocb;
io_end->result = ret;
}
- wq = EXT4_SB(io_end->inode->i_sb)->dio_unwritten_wq;
-
- /* Add the io_end to per-inode completed aio dio list*/
- ei = EXT4_I(io_end->inode);
- spin_lock_irqsave(&ei->i_completed_io_lock, flags);
- list_add_tail(&io_end->list, &ei->i_completed_io_list);
- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
- /* queue the work to convert unwritten extents to written */
- queue_work(wq, &io_end->work);
+ ext4_add_complete_io(io_end);
}
static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
{
ext4_io_end_t *io_end = bh->b_private;
- struct workqueue_struct *wq;
struct inode *inode;
- unsigned long flags;
if (!test_clear_buffer_uninit(bh) || !io_end)
goto out;
@@ -2946,15 +2933,7 @@ static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
*/
inode = io_end->inode;
ext4_set_io_unwritten_flag(inode, io_end);
-
- /* Add the io_end to per-inode completed io list*/
- spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
- list_add_tail(&io_end->list, &EXT4_I(inode)->i_completed_io_list);
- spin_unlock_irqrestore(&EXT4_I(inode)->i_completed_io_lock, flags);
-
- wq = EXT4_SB(inode->i_sb)->dio_unwritten_wq;
- /* queue the work to convert unwritten extents to written */
- queue_work(wq, &io_end->work);
+ ext4_add_complete_io(io_end);
out:
bh->b_private = NULL;
bh->b_end_io = NULL;
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 9970022..5b24c40 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -71,6 +71,7 @@ void ext4_free_io_end(ext4_io_end_t *io)
int i;
BUG_ON(!io);
+ BUG_ON(!list_empty(&io->list));
BUG_ON(io->flag & EXT4_IO_END_UNWRITTEN);
if (io->page)
@@ -83,21 +84,14 @@ void ext4_free_io_end(ext4_io_end_t *io)
kmem_cache_free(io_end_cachep, io);
}
-/*
- * check a range of space and convert unwritten extents to written.
- *
- * Called with inode->i_mutex; we depend on this when we manipulate
- * io->flag, since we could otherwise race with ext4_flush_completed_IO()
- */
-int ext4_end_io_nolock(ext4_io_end_t *io)
+/* check a range of space and convert unwritten extents to written. */
+static int ext4_end_io(ext4_io_end_t *io)
{
struct inode *inode = io->inode;
loff_t offset = io->offset;
ssize_t size = io->size;
int ret = 0;
- BUG_ON(!(io->flag & EXT4_IO_END_UNWRITTEN));
-
ext4_debug("ext4_end_io_nolock: io 0x%p from inode %lu,list->next 0x%p,"
"list->prev 0x%p\n",
io, inode->i_ino, io->list.next, io->list.prev);
@@ -110,7 +104,6 @@ int ext4_end_io_nolock(ext4_io_end_t *io)
"(inode %lu, offset %llu, size %zd, error %d)",
inode->i_ino, offset, size, ret);
}
- io->flag &= ~EXT4_IO_END_UNWRITTEN;
if (io->iocb)
aio_complete(io->iocb, io->result, 0);
@@ -122,51 +115,122 @@ int ext4_end_io_nolock(ext4_io_end_t *io)
return ret;
}
-/*
- * work on completed aio dio IO, to convert unwritten extents to extents
- */
-static void ext4_end_io_work(struct work_struct *work)
+static void dump_completed_IO(struct inode *inode)
+{
+#ifdef EXT4FS_DEBUG
+ struct list_head *cur, *before, *after;
+ ext4_io_end_t *io, *io0, *io1;
+ unsigned long flags;
+
+ if (list_empty(&EXT4_I(inode)->i_completed_io_list)) {
+ ext4_debug("inode %lu completed_io list is empty\n",
+ inode->i_ino);
+ return;
+ }
+
+ ext4_debug("Dump inode %lu completed_io list\n", inode->i_ino);
+ list_for_each_entry(io, &EXT4_I(inode)->i_completed_io_list, list) {
+ cur = &io->list;
+ before = cur->prev;
+ io0 = container_of(before, ext4_io_end_t, list);
+ after = cur->next;
+ io1 = container_of(after, ext4_io_end_t, list);
+
+ ext4_debug("io 0x%p from inode %lu,prev 0x%p,next 0x%p\n",
+ io, inode->i_ino, io0, io1);
+ }
+#endif
+}
+
+/* Add the io_end to per-inode completed end_io list. */
+void ext4_add_complete_io(ext4_io_end_t *io_end)
{
- ext4_io_end_t *io = container_of(work, ext4_io_end_t, work);
- struct inode *inode = io->inode;
- struct ext4_inode_info *ei = EXT4_I(inode);
- unsigned long flags;
+ struct ext4_inode_info *ei = EXT4_I(io_end->inode);
+ struct workqueue_struct *wq;
+ unsigned long flags;
+
+ BUG_ON(!(io_end->flag & EXT4_IO_END_UNWRITTEN));
+ wq = EXT4_SB(io_end->inode->i_sb)->dio_unwritten_wq;
spin_lock_irqsave(&ei->i_completed_io_lock, flags);
- if (io->flag & EXT4_IO_END_IN_FSYNC)
- goto requeue;
- if (list_empty(&io->list)) {
- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
- goto free;
+ if (list_empty(&ei->i_completed_io_list)) {
+ io_end->flag |= EXT4_IO_END_QUEUED;
+ queue_work(wq, &io_end->work);
}
+ list_add_tail(&io_end->list, &ei->i_completed_io_list);
+ spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
+}
- if (!mutex_trylock(&inode->i_mutex)) {
- bool was_queued;
-requeue:
- was_queued = !!(io->flag & EXT4_IO_END_QUEUED);
- io->flag |= EXT4_IO_END_QUEUED;
- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
- /*
- * Requeue the work instead of waiting so that the work
- * items queued after this can be processed.
- */
- queue_work(EXT4_SB(inode->i_sb)->dio_unwritten_wq, &io->work);
- /*
- * To prevent the ext4-dio-unwritten thread from keeping
- * requeueing end_io requests and occupying cpu for too long,
- * yield the cpu if it sees an end_io request that has already
- * been requeued.
- */
- if (was_queued)
- yield();
- return;
+static int ext4_do_flush_completed_IO(struct inode *inode,
+ ext4_io_end_t *work_io)
+{
+ ext4_io_end_t *io;
+ struct list_head unwritten, complete, to_free;
+ unsigned long flags;
+ struct ext4_inode_info *ei = EXT4_I(inode);
+ int err, ret = 0;
+
+ INIT_LIST_HEAD(&complete);
+ INIT_LIST_HEAD(&to_free);
+
+ spin_lock_irqsave(&ei->i_completed_io_lock, flags);
+ dump_completed_IO(inode);
+ list_replace_init(&ei->i_completed_io_list, &unwritten);
+ spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
+
+ while (!list_empty(&unwritten)) {
+ io = list_entry(unwritten.next, ext4_io_end_t, list);
+ BUG_ON(!(io->flag & EXT4_IO_END_UNWRITTEN));
+ list_del_init(&io->list);
+
+ err = ext4_end_io(io);
+ if (unlikely(!ret && err))
+ ret = err;
+
+ list_add_tail(&io->list, &complete);
+ }
+ /* It is important to update all flags for all end_io in one shot w/o
+ * dropping the lock.*/
+ spin_lock_irqsave(&ei->i_completed_io_lock, flags);
+ while (!list_empty(&complete)) {
+ io = list_entry(complete.next, ext4_io_end_t, list);
+ io->flag &= ~EXT4_IO_END_UNWRITTEN;
+ /* end_io context can not be destroyed now because it still
+ * used by queued worker. Worker thread will destroy it later */
+ if (io->flag & EXT4_IO_END_QUEUED)
+ list_del_init(&io->list);
+ else
+ list_move(&io->list, &to_free);
+ }
+ /* If we are called from worker context, it is time to clear queued
+ * flag, and destroy it's end_io if it was converted already */
+ if (work_io) {
+ work_io->flag &= ~EXT4_IO_END_QUEUED;
+ if (!(work_io->flag & EXT4_IO_END_UNWRITTEN))
+ list_add_tail(&work_io->list, &to_free);
}
- list_del_init(&io->list);
spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
- (void) ext4_end_io_nolock(io);
- mutex_unlock(&inode->i_mutex);
-free:
- ext4_free_io_end(io);
+
+ while (!list_empty(&to_free)) {
+ io = list_entry(to_free.next, ext4_io_end_t, list);
+ list_del_init(&io->list);
+ ext4_free_io_end(io);
+ }
+ return ret;
+}
+
+/*
+ * work on completed aio dio IO, to convert unwritten extents to extents
+ */
+static void ext4_end_io_work(struct work_struct *work)
+{
+ ext4_io_end_t *io = container_of(work, ext4_io_end_t, work);
+ ext4_do_flush_completed_IO(io->inode, io);
+}
+
+int ext4_flush_completed_IO(struct inode *inode)
+{
+ return ext4_do_flush_completed_IO(inode, NULL);
}
ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags)
@@ -199,9 +263,7 @@ static void buffer_io_error(struct buffer_head *bh)
static void ext4_end_bio(struct bio *bio, int error)
{
ext4_io_end_t *io_end = bio->bi_private;
- struct workqueue_struct *wq;
struct inode *inode;
- unsigned long flags;
int i;
sector_t bi_sector = bio->bi_sector;
@@ -259,14 +321,7 @@ static void ext4_end_bio(struct bio *bio, int error)
return;
}
- /* Add the io_end to per-inode completed io list*/
- spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
- list_add_tail(&io_end->list, &EXT4_I(inode)->i_completed_io_list);
- spin_unlock_irqrestore(&EXT4_I(inode)->i_completed_io_lock, flags);
-
- wq = EXT4_SB(inode->i_sb)->dio_unwritten_wq;
- /* queue the work to convert unwritten extents to written */
- queue_work(wq, &io_end->work);
+ ext4_add_complete_io(io_end);
}
void ext4_io_submit(struct ext4_io_submit *io)
--
1.7.12.rc0.22.gcdd159b

View File

@ -1,144 +0,0 @@
From 994f567b2e99c82913a279ff438269c771b68a4b Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <dmonakhov@openvz.org>
Date: Sat, 29 Sep 2012 00:41:21 -0400
Subject: [PATCH 05/13] ext4: serialize dio nonlocked reads with defrag
workers
Inode's block defrag and ext4_change_inode_journal_flag() may
affect nonlocked DIO reads result, so proper synchronization
required.
- Add missed inode_dio_wait() calls where appropriate
- Check inode state under extra i_dio_count reference.
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 17335dcc471199717839b2fa3492ca36f70f1168)
Conflicts:
fs/ext4/move_extent.c
---
fs/ext4/ext4.h | 17 +++++++++++++++++
fs/ext4/indirect.c | 14 ++++++++++++++
fs/ext4/inode.c | 5 +++++
fs/ext4/move_extent.c | 8 ++++++++
4 files changed, 44 insertions(+)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 7687d15..3e740e9 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1352,6 +1352,8 @@ enum {
EXT4_STATE_DIO_UNWRITTEN, /* need convert on dio done*/
EXT4_STATE_NEWENTRY, /* File just added to dir */
EXT4_STATE_DELALLOC_RESERVED, /* blks already reserved for delalloc */
+ EXT4_STATE_DIOREAD_LOCK, /* Disable support for dio read
+ nolocking */
};
#define EXT4_INODE_BIT_FNS(name, field, offset) \
@@ -2459,6 +2461,21 @@ static inline void set_bitmap_uptodate(struct buffer_head *bh)
set_bit(BH_BITMAP_UPTODATE, &(bh)->b_state);
}
+/*
+ * Disable DIO read nolock optimization, so new dioreaders will be forced
+ * to grab i_mutex
+ */
+static inline void ext4_inode_block_unlocked_dio(struct inode *inode)
+{
+ ext4_set_inode_state(inode, EXT4_STATE_DIOREAD_LOCK);
+ smp_mb();
+}
+static inline void ext4_inode_resume_unlocked_dio(struct inode *inode)
+{
+ smp_mb();
+ ext4_clear_inode_state(inode, EXT4_STATE_DIOREAD_LOCK);
+}
+
#define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1)
/* For ioend & aio unwritten conversion wait queues */
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
index 61f13e5..8d849da 100644
--- a/fs/ext4/indirect.c
+++ b/fs/ext4/indirect.c
@@ -810,11 +810,25 @@ retry:
if (unlikely(!list_empty(&ei->i_completed_io_list)))
ext4_flush_completed_IO(inode);
+ /*
+ * Nolock dioread optimization may be dynamically disabled
+ * via ext4_inode_block_unlocked_dio(). Check inode's state
+ * while holding extra i_dio_count ref.
+ */
+ atomic_inc(&inode->i_dio_count);
+ smp_mb();
+ if (unlikely(ext4_test_inode_state(inode,
+ EXT4_STATE_DIOREAD_LOCK))) {
+ inode_dio_done(inode);
+ goto locked;
+ }
ret = __blockdev_direct_IO(rw, iocb, inode,
inode->i_sb->s_bdev, iov,
offset, nr_segs,
ext4_get_block, NULL, NULL, 0);
+ inode_dio_done(inode);
} else {
+locked:
ret = blockdev_direct_IO(rw, iocb, inode, iov,
offset, nr_segs, ext4_get_block);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index dd3fd23..2bd7526 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4706,6 +4706,10 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
return err;
}
+ /* Wait for all existing dio workers */
+ ext4_inode_block_unlocked_dio(inode);
+ inode_dio_wait(inode);
+
jbd2_journal_lock_updates(journal);
/*
@@ -4725,6 +4729,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
ext4_set_aops(inode);
jbd2_journal_unlock_updates(journal);
+ ext4_inode_resume_unlocked_dio(inode);
/* Finally we can mark the inode as dirty. */
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index c5826c6..fd1e32e 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -1214,6 +1214,12 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
/* Protect orig and donor inodes against a truncate */
mext_inode_double_lock(orig_inode, donor_inode);
+ /* Wait for all existing dio workers */
+ ext4_inode_block_unlocked_dio(orig_inode);
+ ext4_inode_block_unlocked_dio(donor_inode);
+ inode_dio_wait(orig_inode);
+ inode_dio_wait(donor_inode);
+
/* Protect extent tree against block allocations via delalloc */
double_down_write_data_sem(orig_inode, donor_inode);
/* Check the filesystem environment whether move_extent can be done */
@@ -1413,6 +1419,8 @@ out:
kfree(holecheck_path);
}
double_up_write_data_sem(orig_inode, donor_inode);
+ ext4_inode_resume_unlocked_dio(orig_inode);
+ ext4_inode_resume_unlocked_dio(donor_inode);
mext_inode_double_unlock(orig_inode, donor_inode);
return ret;
--
1.7.12.rc0.22.gcdd159b

View File

@ -1,65 +0,0 @@
From 4c4679fc02744ec3955e88faf5e8b6844fa8cbd3 Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <dmonakhov@openvz.org>
Date: Sat, 29 Sep 2012 00:55:23 -0400
Subject: [PATCH 06/13] ext4: serialize unlocked dio reads with truncate
Current serialization will works only for DIO which holds
i_mutex, but nonlocked DIO following race is possible:
dio_nolock_read_task truncate_task
->ext4_setattr()
->inode_dio_wait()
->ext4_ext_direct_IO
->ext4_ind_direct_IO
->__blockdev_direct_IO
->ext4_get_block
->truncate_setsize()
->ext4_truncate()
#alloc truncated blocks
#to other inode
->submit_io()
#INFORMATION LEAK
In order to serialize with unlocked DIO reads we have to
rearrange wait sequence
1) update i_size first
2) if i_size about to be reduced wait for outstanding DIO requests
3) and only after that truncate inode blocks
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 1c9114f9c0f10f58dd7e568a7152025af47b27e5)
---
fs/ext4/inode.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 2bd7526..b84322d 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4277,7 +4277,6 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
}
if (attr->ia_valid & ATTR_SIZE) {
- inode_dio_wait(inode);
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
@@ -4326,8 +4325,12 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
}
if (attr->ia_valid & ATTR_SIZE) {
- if (attr->ia_size != i_size_read(inode))
+ if (attr->ia_size != i_size_read(inode)) {
truncate_setsize(inode, attr->ia_size);
+ /* Inode size will be reduced, wait for dio in flight */
+ if (orphan)
+ inode_dio_wait(inode);
+ }
ext4_truncate(inode);
}
--
1.7.12.rc0.22.gcdd159b

View File

@ -1,41 +0,0 @@
From ab7b8a329e12369d58e5fa59ba2e2c90370f12ef Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <dmonakhov@openvz.org>
Date: Sat, 29 Sep 2012 00:56:15 -0400
Subject: [PATCH 07/13] ext4: endless truncate due to nonlocked dio readers
If we have enough aggressive DIO readers, truncate and other dio
waiters will wait forever inside inode_dio_wait(). It is reasonable
to disable nonlock DIO read optimization during truncate.
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 1b65007e9870e0021397b548e8cd6bbc584f9152)
---
fs/ext4/inode.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index b84322d..3b03dd6 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4327,9 +4327,14 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
if (attr->ia_valid & ATTR_SIZE) {
if (attr->ia_size != i_size_read(inode)) {
truncate_setsize(inode, attr->ia_size);
- /* Inode size will be reduced, wait for dio in flight */
- if (orphan)
+ /* Inode size will be reduced, wait for dio in flight.
+ * Temporarily disable dioread_nolock to prevent
+ * livelock. */
+ if (orphan) {
+ ext4_inode_block_unlocked_dio(inode);
inode_dio_wait(inode);
+ ext4_inode_resume_unlocked_dio(inode);
+ }
}
ext4_truncate(inode);
}
--
1.7.12.rc0.22.gcdd159b

View File

@ -1,61 +0,0 @@
From 69e4026a2d104ffcf1b935bc889f8abcbfbb29ec Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <dmonakhov@openvz.org>
Date: Sat, 29 Sep 2012 00:58:26 -0400
Subject: [PATCH 08/13] ext4: serialize truncate with owerwrite DIO workers
Jan Kara have spotted interesting issue:
There are potential data corruption issue with direct IO overwrites
racing with truncate:
Like:
dio write truncate_task
->ext4_ext_direct_IO
->overwrite == 1
->down_read(&EXT4_I(inode)->i_data_sem);
->mutex_unlock(&inode->i_mutex);
->ext4_setattr()
->inode_dio_wait()
->truncate_setsize()
->ext4_truncate()
->down_write(&EXT4_I(inode)->i_data_sem);
->__blockdev_direct_IO
->ext4_get_block
->submit_io()
->up_read(&EXT4_I(inode)->i_data_sem);
# truncate data blocks, allocate them to
# other inode - bad stuff happens because
# dio is still in flight.
In order to serialize with truncate dio worker should grab extra i_dio_count
reference before drop i_mutex.
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 1f555cfa29e8f787d675e8390f88ce517a37271a)
---
fs/ext4/inode.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 3b03dd6..484a327 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3008,6 +3008,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
overwrite = *((int *)iocb->private);
if (overwrite) {
+ atomic_inc(&inode->i_dio_count);
down_read(&EXT4_I(inode)->i_data_sem);
mutex_unlock(&inode->i_mutex);
}
@@ -3105,6 +3106,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
retake_lock:
/* take i_mutex locking again if we do a ovewrite dio */
if (overwrite) {
+ inode_dio_done(inode);
up_read(&EXT4_I(inode)->i_data_sem);
mutex_lock(&inode->i_mutex);
}
--
1.7.12.rc0.22.gcdd159b

View File

@ -1,125 +0,0 @@
From 71a6398a4b59ddcf920dfb68872b5a771c606e3a Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <dmonakhov@openvz.org>
Date: Sun, 30 Sep 2012 23:03:42 -0400
Subject: [PATCH 09/13] ext4: punch_hole should wait for DIO writers
punch_hole is the place where we have to wait for all existing writers
(writeback, aio, dio), but currently we simply flush pended end_io request
which is not sufficient. Other issue is that punch_hole performed w/o i_mutex
held which obviously result in dangerous data corruption due to
write-after-free.
This patch performs following changes:
- Guard punch_hole with i_mutex
- Recheck inode flags under i_mutex
- Block all new dio readers in order to prevent information leak caused by
read-after-free pattern.
- punch_hole now wait for all writers in flight
NOTE: XXX write-after-free race is still possible because new dirty pages
may appear due to mmap(), and currently there is no easy way to stop
writeback while punch_hole is in progress.
[ Fixed error return from ext4_ext_punch_hole() to make sure that we
release i_mutex before returning EPERM or ETXTBUSY -- Ted ]
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 02d262dffcf4c74e5c4612ee736bdb94f18ed5b9)
---
fs/ext4/extents.c | 53 ++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 36 insertions(+), 17 deletions(-)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 1fbf2ff..202eb4d 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4776,9 +4776,32 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
loff_t first_page_offset, last_page_offset;
int credits, err = 0;
+ /*
+ * Write out all dirty pages to avoid race conditions
+ * Then release them.
+ */
+ if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
+ err = filemap_write_and_wait_range(mapping,
+ offset, offset + length - 1);
+
+ if (err)
+ return err;
+ }
+
+ mutex_lock(&inode->i_mutex);
+ /* It's not possible punch hole on append only file */
+ if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
+ err = -EPERM;
+ goto out_mutex;
+ }
+ if (IS_SWAPFILE(inode)) {
+ err = -ETXTBSY;
+ goto out_mutex;
+ }
+
/* No need to punch hole beyond i_size */
if (offset >= inode->i_size)
- return 0;
+ goto out_mutex;
/*
* If the hole extends beyond i_size, set the hole
@@ -4796,33 +4819,25 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
first_page_offset = first_page << PAGE_CACHE_SHIFT;
last_page_offset = last_page << PAGE_CACHE_SHIFT;
- /*
- * Write out all dirty pages to avoid race conditions
- * Then release them.
- */
- if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
- err = filemap_write_and_wait_range(mapping,
- offset, offset + length - 1);
-
- if (err)
- return err;
- }
-
/* Now release the pages */
if (last_page_offset > first_page_offset) {
truncate_pagecache_range(inode, first_page_offset,
last_page_offset - 1);
}
- /* finish any pending end_io work */
+ /* Wait all existing dio workers, newcomers will block on i_mutex */
+ ext4_inode_block_unlocked_dio(inode);
+ inode_dio_wait(inode);
err = ext4_flush_completed_IO(inode);
if (err)
- return err;
+ goto out_dio;
credits = ext4_writepage_trans_blocks(inode);
handle = ext4_journal_start(inode, credits);
- if (IS_ERR(handle))
- return PTR_ERR(handle);
+ if (IS_ERR(handle)) {
+ err = PTR_ERR(handle);
+ goto out_dio;
+ }
err = ext4_orphan_add(handle, inode);
if (err)
@@ -4916,6 +4931,10 @@ out:
inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
ext4_mark_inode_dirty(handle, inode);
ext4_journal_stop(handle);
+out_dio:
+ ext4_inode_resume_unlocked_dio(inode);
+out_mutex:
+ mutex_unlock(&inode->i_mutex);
return err;
}
int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
--
1.7.12.rc0.22.gcdd159b

View File

@ -1,60 +0,0 @@
From 66d08dd92b82dabfd64853aa4edde1547fdf9ef7 Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <dmonakhov@openvz.org>
Date: Sun, 30 Sep 2012 23:03:50 -0400
Subject: [PATCH 10/13] ext4: fix ext_remove_space for punch_hole case
Inode is allowed to have empty leaf only if it this is blockless inode.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 6f2080e64487b9963f9c6ff8a252e1abce98f2d4)
---
fs/ext4/extents.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 202eb4d..b1c92c0 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2572,7 +2572,7 @@ static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
struct ext4_ext_path *path = NULL;
ext4_fsblk_t partial_cluster = 0;
handle_t *handle;
- int i = 0, err;
+ int i = 0, err = 0;
ext_debug("truncate since %u to %u\n", start, end);
@@ -2604,12 +2604,16 @@ again:
return PTR_ERR(path);
}
depth = ext_depth(inode);
+ /* Leaf not may not exist only if inode has no blocks at all */
ex = path[depth].p_ext;
if (!ex) {
- ext4_ext_drop_refs(path);
- kfree(path);
- path = NULL;
- goto cont;
+ if (depth) {
+ EXT4_ERROR_INODE(inode,
+ "path[%d].p_hdr == NULL",
+ depth);
+ err = -EIO;
+ }
+ goto out;
}
ee_block = le32_to_cpu(ex->ee_block);
@@ -2641,8 +2645,6 @@ again:
goto out;
}
}
-cont:
-
/*
* We start scanning from right side, freeing all the blocks
* after i_size and walking into the tree depth-wise.
--
1.7.12.rc0.22.gcdd159b

View File

@ -1,176 +0,0 @@
From ca6d3910cbf8854f3f3b9846391f669733899101 Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <dmonakhov@openvz.org>
Date: Fri, 5 Oct 2012 11:31:55 -0400
Subject: [PATCH 11/13] ext4: fix ext4_flush_completed_IO wait semantics
BUG #1) All places where we call ext4_flush_completed_IO are broken
because buffered io and DIO/AIO goes through three stages
1) submitted io,
2) completed io (in i_completed_io_list) conversion pended
3) finished io (conversion done)
And by calling ext4_flush_completed_IO we will flush only
requests which were in (2) stage, which is wrong because:
1) punch_hole and truncate _must_ wait for all outstanding unwritten io
regardless to it's state.
2) fsync and nolock_dio_read should also wait because there is
a time window between end_page_writeback() and ext4_add_complete_io()
As result integrity fsync is broken in case of buffered write
to fallocated region:
fsync blkdev_completion
->filemap_write_and_wait_range
->ext4_end_bio
->end_page_writeback
<-- filemap_write_and_wait_range return
->ext4_flush_completed_IO
sees empty i_completed_io_list but pended
conversion still exist
->ext4_add_complete_io
BUG #2) Race window becomes wider due to the 'ext4: completed_io
locking cleanup V4' patch series
This patch make following changes:
1) ext4_flush_completed_io() now first try to flush completed io and when
wait for any outstanding unwritten io via ext4_unwritten_wait()
2) Rename function to more appropriate name.
3) Assert that all callers of ext4_flush_unwritten_io should hold i_mutex to
prevent endless wait
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Jan Kara <jack@suse.cz>
(cherry picked from commit c278531d39f3158bfee93dc67da0b77e09776de2)
---
fs/ext4/ext4.h | 3 ++-
fs/ext4/extents.c | 6 +++---
fs/ext4/file.c | 2 +-
fs/ext4/fsync.c | 2 +-
fs/ext4/indirect.c | 8 +++++---
fs/ext4/page-io.c | 11 +++++++----
6 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 3e740e9..7f13292 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1941,7 +1941,7 @@ extern void ext4_htree_free_dir_info(struct dir_private_info *p);
/* fsync.c */
extern int ext4_sync_file(struct file *, loff_t, loff_t, int);
-extern int ext4_flush_completed_IO(struct inode *);
+extern int ext4_flush_unwritten_io(struct inode *);
/* hash.c */
extern int ext4fs_dirhash(const char *name, int len, struct
@@ -2361,6 +2361,7 @@ extern const struct file_operations ext4_dir_operations;
extern const struct inode_operations ext4_file_inode_operations;
extern const struct file_operations ext4_file_operations;
extern loff_t ext4_llseek(struct file *file, loff_t offset, int origin);
+extern void ext4_unwritten_wait(struct inode *inode);
/* namei.c */
extern const struct inode_operations ext4_dir_inode_operations;
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index b1c92c0..37f46eb 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4250,7 +4250,7 @@ void ext4_ext_truncate(struct inode *inode)
* finish any pending end_io work so we won't run the risk of
* converting any truncated blocks to initialized later
*/
- ext4_flush_completed_IO(inode);
+ ext4_flush_unwritten_io(inode);
/*
* probably first extent we're gonna free will be last in block
@@ -4829,10 +4829,10 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
/* Wait all existing dio workers, newcomers will block on i_mutex */
ext4_inode_block_unlocked_dio(inode);
- inode_dio_wait(inode);
- err = ext4_flush_completed_IO(inode);
+ err = ext4_flush_unwritten_io(inode);
if (err)
goto out_dio;
+ inode_dio_wait(inode);
credits = ext4_writepage_trans_blocks(inode);
handle = ext4_journal_start(inode, credits);
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 39335bd..ca6f07a 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -55,7 +55,7 @@ static int ext4_release_file(struct inode *inode, struct file *filp)
return 0;
}
-static void ext4_unwritten_wait(struct inode *inode)
+void ext4_unwritten_wait(struct inode *inode)
{
wait_queue_head_t *wq = ext4_ioend_wq(inode);
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
index 520b058..76051c6 100644
--- a/fs/ext4/fsync.c
+++ b/fs/ext4/fsync.c
@@ -138,7 +138,7 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
if (inode->i_sb->s_flags & MS_RDONLY)
goto out;
- ret = ext4_flush_completed_IO(inode);
+ ret = ext4_flush_unwritten_io(inode);
if (ret < 0)
goto out;
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
index 8d849da..792e388 100644
--- a/fs/ext4/indirect.c
+++ b/fs/ext4/indirect.c
@@ -807,9 +807,11 @@ ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
retry:
if (rw == READ && ext4_should_dioread_nolock(inode)) {
- if (unlikely(!list_empty(&ei->i_completed_io_list)))
- ext4_flush_completed_IO(inode);
-
+ if (unlikely(atomic_read(&EXT4_I(inode)->i_unwritten))) {
+ mutex_lock(&inode->i_mutex);
+ ext4_flush_unwritten_io(inode);
+ mutex_unlock(&inode->i_mutex);
+ }
/*
* Nolock dioread optimization may be dynamically disabled
* via ext4_inode_block_unlocked_dio(). Check inode's state
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 5b24c40..68e896e 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -189,8 +189,6 @@ static int ext4_do_flush_completed_IO(struct inode *inode,
list_add_tail(&io->list, &complete);
}
- /* It is important to update all flags for all end_io in one shot w/o
- * dropping the lock.*/
spin_lock_irqsave(&ei->i_completed_io_lock, flags);
while (!list_empty(&complete)) {
io = list_entry(complete.next, ext4_io_end_t, list);
@@ -228,9 +226,14 @@ static void ext4_end_io_work(struct work_struct *work)
ext4_do_flush_completed_IO(io->inode, io);
}
-int ext4_flush_completed_IO(struct inode *inode)
+int ext4_flush_unwritten_io(struct inode *inode)
{
- return ext4_do_flush_completed_IO(inode, NULL);
+ int ret;
+ WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex) &&
+ !(inode->i_state & I_FREEING));
+ ret = ext4_do_flush_completed_IO(inode, NULL);
+ ext4_unwritten_wait(inode);
+ return ret;
}
ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags)
--
1.7.12.rc0.22.gcdd159b

View File

@ -1,46 +0,0 @@
From 9f00d109efeaf4d12d56c8e46cd13af80e344f97 Mon Sep 17 00:00:00 2001
From: Dmitry Monakhov <dmonakhov@openvz.org>
Date: Fri, 5 Oct 2012 11:32:02 -0400
Subject: [PATCH 12/13] ext4: serialize fallocate with
ext4_convert_unwritten_extents
Fallocate should wait for pended ext4_convert_unwritten_extents()
otherwise following race may happen:
ftruncate( ,12288);
fallocate( ,0, 4096)
io_sibmit( ,0, 4096); /* Write to fallocated area, split extent if needed */
fallocate( ,0, 8192); /* Grow extent and broke assumption about extent */
Later kwork completion will do:
->ext4_convert_unwritten_extents (0, 4096)
->ext4_map_blocks(handle, inode, &map, EXT4_GET_BLOCKS_IO_CONVERT_EXT);
->ext4_ext_map_blocks() /* Will find new extent: ex = [0,2] !!!!!! */
->ext4_ext_handle_uninitialized_extents()
->ext4_convert_unwritten_extents_endio()
/* convert [0,2] extent to initialized, but only[0,1] was written */
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 60d4616f3dc63371b3dc367e5e88fd4b4f037f65)
---
fs/ext4/extents.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 37f46eb..ea2db86 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4410,6 +4410,9 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
*/
if (len <= EXT_UNINIT_MAX_LEN << blkbits)
flags |= EXT4_GET_BLOCKS_NO_NORMALIZE;
+
+ /* Prevent race condition between unwritten */
+ ext4_flush_unwritten_io(inode);
retry:
while (ret >= 0 && ret < max_blocks) {
map.m_lblk = map.m_lblk + ret;
--
1.7.12.rc0.22.gcdd159b

View File

@ -1,46 +0,0 @@
From b7e383046c2c7c13ad928cd7407eafff758ddd4b Mon Sep 17 00:00:00 2001
From: Zhang Rui <rui.zhang@intel.com>
Date: Tue, 4 Dec 2012 23:23:16 +0100
Subject: [PATCH] ACPI : do not use Lid and Sleep button for S5 wakeup
When system enters power off, the _PSW of Lid device is enabled.
But this may cause the system to reboot instead of power off.
A proper way to fix this is to always disable lid wakeup capability for S5.
References: https://bugzilla.kernel.org/show_bug.cgi?id=35262
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/acpi/scan.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index d0b38ab..bd523bf 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -917,8 +917,8 @@ acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
{
struct acpi_device_id button_device_ids[] = {
- {"PNP0C0D", 0},
{"PNP0C0C", 0},
+ {"PNP0C0D", 0},
{"PNP0C0E", 0},
{"", 0},
};
@@ -930,6 +930,11 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
/* Power button, Lid switch always enable wakeup */
if (!acpi_match_device_ids(device, button_device_ids)) {
device->wakeup.flags.run_wake = 1;
+ if (!acpi_match_device_ids(device, &button_device_ids[1])) {
+ /* Do not use Lid/sleep button for S5 wakeup */
+ if (device->wakeup.sleep_state == ACPI_STATE_S5)
+ device->wakeup.sleep_state = ACPI_STATE_S4;
+ }
device_set_wakeup_capable(&device->dev, true);
return;
}
--
1.8.0.1

View File

@ -1,107 +0,0 @@
From 7f198e1cc6d4fda9c84c0da4fc3aafb441342f78 Mon Sep 17 00:00:00 2001
From: Jaroslav Resler <resler@cs.cas.cz>
Date: Tue, 11 Sep 2012 17:25:32 +0800
Subject: [PATCH 1/2] Bluetooth: Add support for BCM20702A0 [04ca, 2003]
Add another vendor specific ID for BCM20702A0.
output of usb-devices:
T: Bus=01 Lev=02 Prnt=02 Port=03 Cnt=02 Dev#= 4 Spd=12 MxCh= 0
D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=04ca ProdID=2003 Rev= 1.12
S: Manufacturer=Broadcom Corp
S: Product=BCM20702A0
S: SerialNumber=446D57861623
C:* #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr= 0mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
I: If#= 1 Alt= 1 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
I: If#= 1 Alt= 2 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
I: If#= 1 Alt= 3 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
I: If#= 1 Alt= 4 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
I: If#= 1 Alt= 5 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
E: Ad=84(I) Atr=02(Bulk) MxPS= 32 Ivl=0ms
E: Ad=04(O) Atr=02(Bulk) MxPS= 32 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none)
Signed-off-by: Cho, Yu-Chen <acho@suse.com>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
drivers/bluetooth/btusb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 654e248..b167944 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -96,6 +96,7 @@ static struct usb_device_id btusb_table[] = {
{ USB_DEVICE(0x0c10, 0x0000) },
/* Broadcom BCM20702A0 */
+ { USB_DEVICE(0x04ca, 0x2003) },
{ USB_DEVICE(0x0489, 0xe042) },
{ USB_DEVICE(0x413c, 0x8197) },
--
1.8.0
From a5f86c3423428c8e28b6501d0e9c3929ca91f07d Mon Sep 17 00:00:00 2001
From: Jeff Cook <jeff@deserettechnology.com>
Date: Fri, 9 Nov 2012 16:39:48 -0700
Subject: [PATCH 2/2] Bluetooth: Add support for BCM20702A0 [0b05, 17b5]
Vendor-specific ID for BCM20702A0.
Support for bluetooth over Asus Wi-Fi GO!, included with Asus P8Z77-V
Deluxe.
T: Bus=07 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=12 MxCh= 0
D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=0b05 ProdID=17b5 Rev=01.12
S: Manufacturer=Broadcom Corp
S: Product=BCM20702A0
S: SerialNumber=94DBC98AC113
C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=0mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
I: If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none)
Cc: stable@vger.kernel.org
Signed-off-by: Jeff Cook <jeff@deserettechnology.com>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
drivers/bluetooth/btusb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index b167944..6dc44ff 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -96,6 +96,7 @@ static struct usb_device_id btusb_table[] = {
{ USB_DEVICE(0x0c10, 0x0000) },
/* Broadcom BCM20702A0 */
+ { USB_DEVICE(0x0b05, 0x17b5) },
{ USB_DEVICE(0x04ca, 0x2003) },
{ USB_DEVICE(0x0489, 0xe042) },
{ USB_DEVICE(0x413c, 0x8197) },
--
1.8.0

View File

@ -1,102 +0,0 @@
From 95ab000388974d8ffef8257306b4be6e8778b768 Mon Sep 17 00:00:00 2001
From: Jianpeng Ma <majianpeng@gmail.com>
Date: Sat, 4 Aug 2012 10:34:14 +0800
Subject: [PATCH] [SCSI] mvsas: Fix oops when ata commond timeout.
Kernel message follows:
[ 511.712011] sd 11:0:0:0: [sdf] command ffff8800a4e81400 timed out
[ 511.712022] sas: Enter sas_scsi_recover_host busy: 1 failed: 1
[ 511.712024] sas: trying to find task 0xffff8800a4d24c80
[ 511.712026] sas: sas_scsi_find_task: aborting task 0xffff8800a4d24c80
[ 511.712029] drivers/scsi/mvsas/mv_sas.c 1631:mvs_abort_task()
mvi=ffff8800b5300000 task=ffff8800a4d24c80 slot=ffff8800b5325038
slot_idx=x0
[ 511.712035] BUG: unable to handle kernel NULL pointer dereference at
0000000000000058
[ 511.712040] IP: [<ffffffff815f8c0c>] _raw_spin_lock_irqsave+0xc/0x30
[ 511.712047] PGD 0
[ 511.712049] Oops: 0002 [#1] SMP
[ 511.712052] Modules linked in: mvsas libsas scsi_transport_sas
raid456 async_pq async_xor xor async_memcpy async_raid6_recov raid6_pq
async_tx [last unloaded: mvsas]
[ 511.712062] CPU 3
[ 511.712066] Pid: 7322, comm: scsi_eh_11 Not tainted 3.5.0+ #106 To Be
Filled By O.E.M. To Be Filled By O.E.M./To be filled by O.E.M.
[ 511.712068] RIP: 0010:[<ffffffff815f8c0c>] [<ffffffff815f8c0c>]
_raw_spin_lock_irqsave+0xc/0x30
[ 511.712073] RSP: 0018:ffff880098d3bcb0 EFLAGS: 00010086
[ 511.712074] RAX: 0000000000000286 RBX: 0000000000000058 RCX:
00000000000000c3
[ 511.712076] RDX: 0000000000000100 RSI: 0000000000000046 RDI:
0000000000000058
[ 511.712078] RBP: ffff880098d3bcb0 R08: 000000000000000a R09:
0000000000000000
[ 511.712080] R10: 00000000000004e8 R11: 00000000000004e7 R12:
ffff8800a4d24c80
[ 511.712082] R13: 0000000000000050 R14: ffff8800b5325038 R15:
ffff8800a4eafe00
[ 511.712084] FS: 0000000000000000(0000) GS:ffff8800bdb80000(0000)
knlGS:0000000000000000
[ 511.712086] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 511.712088] CR2: 0000000000000058 CR3: 00000000a4ce6000 CR4:
00000000000407e0
[ 511.712090] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
0000000000000000
[ 511.712091] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7:
0000000000000400
[ 511.712093] Process scsi_eh_11 (pid: 7322, threadinfo
ffff880098d3a000, task ffff8800a61dde40)
[ 511.712095] Stack:
[ 511.712096] ffff880098d3bce0 ffffffff81060683 ffff880000000000
0000000000000000
[ 511.712099] ffff8800a4d24c80 ffff8800b5300000 ffff880098d3bcf0
ffffffffa0076a88
[ 511.712102] ffff880098d3bd50 ffffffffa0079bb5 ffff880000000000
ffff880000000018
[ 511.712106] Call Trace:
[ 511.712110] [<ffffffff81060683>] complete+0x23/0x60
[ 511.712115] [<ffffffffa0076a88>] mvs_tmf_timedout+0x18/0x20 [mvsas]
[ 511.712119] [<ffffffffa0079bb5>] mvs_slot_complete+0x765/0x7d0
[mvsas]
[ 511.712125] [<ffffffffa005a17d>] sas_scsi_recover_host+0x55d/0xdb0
[libsas]
[ 511.712128] [<ffffffff8106d600>] ? idle_balance+0xe0/0x130
[ 511.712133] [<ffffffff813b150c>] scsi_error_handler+0xcc/0x470
[ 511.712136] [<ffffffff815f7ad0>] ? __schedule+0x370/0x730
[ 511.712139] [<ffffffff8105f728>] ? __wake_up_common+0x58/0x90
[ 511.712142] [<ffffffff813b1440>] ? scsi_eh_get_sense+0x110/0x110
[ 511.712146] [<ffffffff810571be>] kthread+0x8e/0xa0
[ 511.712150] [<ffffffff816015f4>] kernel_thread_helper+0x4/0x10
[ 511.712153] [<ffffffff81057130>] ? flush_kthread_work+0x120/0x120
[ 511.712156] [<ffffffff816015f0>] ? gs_change+0xb/0xb
[ 511.712157] Code: 8a 00 01 00 00 89 d0 f0 66 0f b1 0f 66 39 d0 0f 94
c0 0f b6 c0 5d c3 0f 1f 84 00 00 00 00 00 55 48 89 e5 9c 58 fa ba 00 01
00 00 <f0> 66 0f c1 17 0f b6 ce 38 d1 74 11 0f 1f 84 00 00 00 00 00 f3
[ 511.712191] RIP [<ffffffff815f8c0c>] _raw_spin_lock_irqsave+0xc/0x30
[ 511.712194] RSP <ffff880098d3bcb0>
[ 511.712196] CR2: 0000000000000058
[ 511.712198] ---[ end trace a781c7b1e65db92c ]---
Signed-off-by: Jianpeng Ma <majianpeng@gmail.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
---
drivers/scsi/mvsas/mv_sas.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index 4539d59..a3776d6 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -1629,7 +1629,7 @@ int mvs_abort_task(struct sas_task *task)
mv_dprintk("mvs_abort_task() mvi=%p task=%p "
"slot=%p slot_idx=x%x\n",
mvi, task, slot, slot_idx);
- mvs_tmf_timedout((unsigned long)task);
+ task->task_state_flags |= SAS_TASK_STATE_ABORTED;
mvs_slot_task_free(mvi, task, slot, slot_idx);
rc = TMF_RESP_FUNC_COMPLETE;
goto out;
--
1.8.0

View File

@ -1,78 +0,0 @@
Lines: 75
On Thu, Jan 03, 2013 at 12:15:35PM -0600, Ed Cashin wrote:
...
> >>>>> On Jan 3, 2013, at 8:25 AM, Josh Boyer wrote:
...
> >>>>>> [699170.611997] aoe: AoE v47 initialised.
...
> >>>>>> [699231.308319] WARNING: at lib/list_debug.c:62 __list_del_entry+0x82/0xd0()
> >>>>>> [699231.312031] Hardware name: S5000VSA
> >>>>>> [699231.315658] list_del corruption. next->prev should be ffff880009fa37e8, but was ffffffff81c79c00
> >>>>>> [699231.319352] Modules linked in: aoe(-) ip6table_filter ip6_tables ebtable_nat ebtables lockd sunrpc bridge 8021q garp stp llc vfat fat binfmt_misc iTCO_wdt iTCO_vendor_support vhost_net lpc_ich radeon tun macvtap mfd_core serio_raw coretemp i2c_algo_bit ttm i5000_edac macvlan drm_kms_helper e1000e edac_core microcode i5k_amb shpchp i2c_i801 drm kvm_intel i2c_core kvm ioatdma dca raid1
> >>>>>> [699231.336259] Pid: 8584, comm: modprobe Not tainted 3.6.11-1.fc17.x86_64 #1
> >>>>>> [699231.340561] Call Trace:
> >>>>>> [699231.344865] [<ffffffff8105c8ef>] warn_slowpath_common+0x7f/0xc0
> >>>>>> [699231.349212] [<ffffffff8105c9e6>] warn_slowpath_fmt+0x46/0x50
> >>>>>> [699231.353595] [<ffffffff812eee52>] __list_del_entry+0x82/0xd0
> >>>>>> [699231.357954] [<ffffffff812eeeb1>] list_del+0x11/0x40
> >>>>>> [699231.362319] [<ffffffff812f6458>] percpu_counter_destroy+0x28/0x50
> >>>>>> [699231.366712] [<ffffffff8114c513>] bdi_destroy+0x43/0x140
> >>>>>> [699231.371127] [<ffffffff812be20c>] blk_release_queue+0x8c/0xc0
> >>>>>> [699231.375454] [<ffffffff812dc322>] kobject_cleanup+0x82/0x1b0
> >>>>>> [699231.379675] [<ffffffff812dc1ab>] kobject_put+0x2b/0x60
> >>>>>> [699231.383851] [<ffffffff812b80a5>] blk_put_queue+0x15/0x20
> >>>>>> [699231.387899] [<ffffffff812bc659>] blk_cleanup_queue+0xc9/0xe0
> >>>>>> [699231.391794] [<ffffffffa01f53f5>] aoedev_freedev+0x135/0x150 [aoe]
> >>>>>> [699231.395668] [<ffffffffa01f59a5>] aoedev_exit+0x65/0x80 [aoe]
> >>>>>> [699231.399493] [<ffffffffa01f5afe>] aoe_exit+0x2e/0x40 [aoe]
> >>>>>> [699231.403273] [<ffffffff810bdefe>] sys_delete_module+0x16e/0x2d0
> >>>>>> [699231.407119] [<ffffffff8161db56>] ? __schedule+0x3c6/0x7a0
> >>>>>> [699231.411050] [<ffffffff8119054a>] ? sys_write+0x4a/0x90
> >>>>>> [699231.415033] [<ffffffff81627329>] system_call_fastpath+0x16/0x1b
> >>>>>> [699231.419117] ---[ end trace 9e1558af1964b569 ]---
> >>>>>> [699231.423248] ------------[ cut here ]------------
The blk_alloc_queue has already done a bdi_init, so do not bdi_init again in
aoeblk_gdalloc.
The patch below applies to v3.5.6, with its v47 aoe driver. On my system it
eliminates the list_del corruption messages.
It updates VERSION for convenience during testing.
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index db195ab..2ccb9e2 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */
-#define VERSION "47"
+#define VERSION "47nobdi1"
#define AOE_MAJOR 152
#define DEVICE_NAME "aoe"
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 321de7b..7eca463 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -276,8 +276,6 @@ aoeblk_gdalloc(void *vp)
goto err_mempool;
blk_queue_make_request(d->blkq, aoeblk_make_request);
d->blkq->backing_dev_info.name = "aoe";
- if (bdi_init(&d->blkq->backing_dev_info))
- goto err_blkq;
spin_lock_irqsave(&d->lock, flags);
gd->major = AOE_MAJOR;
gd->first_minor = d->sysminor * AOE_PARTITIONS;
@@ -298,9 +296,6 @@ aoeblk_gdalloc(void *vp)
aoedisk_add_sysfs(d);
return;
-err_blkq:
- blk_cleanup_queue(d->blkq);
- d->blkq = NULL;
err_mempool:
mempool_destroy(d->bufpool);
err_disk:

View File

@ -1,15 +0,0 @@
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index ff3af6e..f99fa25 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -2,8 +2,8 @@
config SND_TEA575X
tristate
- depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 || RADIO_MAXIRADIO
- default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 || RADIO_MAXIRADIO
+ depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 || RADIO_MAXIRADIO || RADIO_SHARK
+ default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 || RADIO_MAXIRADIO || RADIO_SHARK
menuconfig SND_PCI
bool "PCI sound devices"

View File

@ -1,599 +0,0 @@
From: Mark Langsdorf <mark.langsdorf@calxeda.com>
Date: Thu, 6 Sep 2012 21:03:30 +0000 (-0500)
Subject: ata: add platform driver for Calxeda AHCI controller
X-Git-Tag: next-20121002~68^2~5
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fnext%2Flinux-next.git;a=commitdiff_plain;h=8996b89d6bc98ae2f6d6e6e624a42a3f89d06949;hp=100f586bd0959fe0e52b8a0b8cb49a3df1c6b044
ata: add platform driver for Calxeda AHCI controller
Calxeda highbank SATA phy has intermittent problems bringing up a link
with Gen3 drives. Retrying the phy hard reset can work-around this issue,
but each reset also disables spread spectrum support. The reset function
also needs to reprogram the phy to enable spread spectrum support.
Create a new driver based on ahci_platform to support the Calxeda Highbank
SATA controller.
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
---
diff --git a/Documentation/devicetree/bindings/arm/calxeda/combophy.txt b/Documentation/devicetree/bindings/arm/calxeda/combophy.txt
new file mode 100644
index 0000000..6622bdb
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/calxeda/combophy.txt
@@ -0,0 +1,17 @@
+Calxeda Highbank Combination Phys for SATA
+
+Properties:
+- compatible : Should be "calxeda,hb-combophy"
+- #phy-cells: Should be 1.
+- reg : Address and size for Combination Phy registers.
+- phydev: device ID for programming the combophy.
+
+Example:
+
+ combophy5: combo-phy@fff5d000 {
+ compatible = "calxeda,hb-combophy";
+ #phy-cells = <1>;
+ reg = <0xfff5d000 0x1000>;
+ phydev = <31>;
+ };
+
diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
index 8bb8a76..147c1f6 100644
--- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
@@ -8,9 +8,17 @@ Required properties:
- interrupts : <interrupt mapping for SATA IRQ>
- reg : <registers mapping>
+Optional properties:
+- calxeda,port-phys: phandle-combophy and lane assignment, which maps each
+ SATA port to a combophy and a lane within that
+ combophy
+
Example:
sata@ffe08000 {
compatible = "calxeda,hb-ahci";
reg = <0xffe08000 0x1000>;
interrupts = <115>;
+ calxeda,port-phys = <&combophy5 0 &combophy0 0 &combophy0 1
+ &combophy0 2 &combophy0 3>;
+
};
diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
index 9fecf1a..5204cf7 100644
--- a/arch/arm/boot/dts/highbank.dts
+++ b/arch/arm/boot/dts/highbank.dts
@@ -121,6 +121,9 @@
compatible = "calxeda,hb-ahci";
reg = <0xffe08000 0x10000>;
interrupts = <0 83 4>;
+ calxeda,port-phys = <&combophy5 0 &combophy0 0
+ &combophy0 1 &combophy0 2
+ &combophy0 3>;
};
sdhci@ffe0e000 {
@@ -306,5 +309,19 @@
reg = <0xfff51000 0x1000>;
interrupts = <0 80 4 0 81 4 0 82 4>;
};
+
+ combophy0: combo-phy@fff58000 {
+ compatible = "calxeda,hb-combophy";
+ #phy-cells = <1>;
+ reg = <0xfff58000 0x1000>;
+ phydev = <5>;
+ };
+
+ combophy5: combo-phy@fff5d000 {
+ compatible = "calxeda,hb-combophy";
+ #phy-cells = <1>;
+ reg = <0xfff5d000 0x1000>;
+ phydev = <31>;
+ };
};
};
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 27cecd3..e08d322 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -214,6 +214,14 @@ config SATA_DWC_VDEBUG
help
This option enables the taskfile dumping and NCQ debugging.
+config SATA_HIGHBANK
+ tristate "Calxeda Highbank SATA support"
+ help
+ This option enables support for the Calxeda Highbank SoC's
+ onboard SATA.
+
+ If unsure, say N.
+
config SATA_MV
tristate "Marvell SATA support"
help
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index a454a13..8b384f1 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_SATA_FSL) += sata_fsl.o
obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
+obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o
# SFF w/ custom DMA
obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 09728e0..dc187c7 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -277,7 +277,6 @@ static int ahci_resume(struct device *dev)
SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume);
static const struct of_device_id ahci_of_match[] = {
- { .compatible = "calxeda,hb-ahci", },
{ .compatible = "snps,spear-ahci", },
{},
};
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c
new file mode 100644
index 0000000..0d7c4c2
--- /dev/null
+++ b/drivers/ata/sata_highbank.c
@@ -0,0 +1,450 @@
+/*
+ * Calxeda Highbank AHCI SATA platform driver
+ * Copyright 2012 Calxeda, Inc.
+ *
+ * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/kernel.h>
+#include <linux/gfp.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/libata.h>
+#include <linux/ahci_platform.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/export.h>
+#include "ahci.h"
+
+#define CPHY_MAP(dev, addr) ((((dev) & 0x1f) << 7) | (((addr) >> 9) & 0x7f))
+#define CPHY_ADDR(addr) (((addr) & 0x1ff) << 2)
+#define SERDES_CR_CTL 0x80a0
+#define SERDES_CR_ADDR 0x80a1
+#define SERDES_CR_DATA 0x80a2
+#define CR_BUSY 0x0001
+#define CR_START 0x0001
+#define CR_WR_RDN 0x0002
+#define CPHY_RX_INPUT_STS 0x2002
+#define CPHY_SATA_OVERRIDE 0x4000
+#define CPHY_OVERRIDE 0x2005
+#define SPHY_LANE 0x100
+#define SPHY_HALF_RATE 0x0001
+#define CPHY_SATA_DPLL_MODE 0x0700
+#define CPHY_SATA_DPLL_SHIFT 8
+#define CPHY_SATA_DPLL_RESET (1 << 11)
+#define CPHY_PHY_COUNT 6
+#define CPHY_LANE_COUNT 4
+#define CPHY_PORT_COUNT (CPHY_PHY_COUNT * CPHY_LANE_COUNT)
+
+static DEFINE_SPINLOCK(cphy_lock);
+/* Each of the 6 phys can have up to 4 sata ports attached to i. Map 0-based
+ * sata ports to their phys and then to their lanes within the phys
+ */
+struct phy_lane_info {
+ void __iomem *phy_base;
+ u8 lane_mapping;
+ u8 phy_devs;
+};
+static struct phy_lane_info port_data[CPHY_PORT_COUNT];
+
+static u32 __combo_phy_reg_read(u8 sata_port, u32 addr)
+{
+ u32 data;
+ u8 dev = port_data[sata_port].phy_devs;
+ spin_lock(&cphy_lock);
+ writel(CPHY_MAP(dev, addr), port_data[sata_port].phy_base + 0x800);
+ data = readl(port_data[sata_port].phy_base + CPHY_ADDR(addr));
+ spin_unlock(&cphy_lock);
+ return data;
+}
+
+static void __combo_phy_reg_write(u8 sata_port, u32 addr, u32 data)
+{
+ u8 dev = port_data[sata_port].phy_devs;
+ spin_lock(&cphy_lock);
+ writel(CPHY_MAP(dev, addr), port_data[sata_port].phy_base + 0x800);
+ writel(data, port_data[sata_port].phy_base + CPHY_ADDR(addr));
+ spin_unlock(&cphy_lock);
+}
+
+static void combo_phy_wait_for_ready(u8 sata_port)
+{
+ while (__combo_phy_reg_read(sata_port, SERDES_CR_CTL) & CR_BUSY)
+ udelay(5);
+}
+
+static u32 combo_phy_read(u8 sata_port, u32 addr)
+{
+ combo_phy_wait_for_ready(sata_port);
+ __combo_phy_reg_write(sata_port, SERDES_CR_ADDR, addr);
+ __combo_phy_reg_write(sata_port, SERDES_CR_CTL, CR_START);
+ combo_phy_wait_for_ready(sata_port);
+ return __combo_phy_reg_read(sata_port, SERDES_CR_DATA);
+}
+
+static void combo_phy_write(u8 sata_port, u32 addr, u32 data)
+{
+ combo_phy_wait_for_ready(sata_port);
+ __combo_phy_reg_write(sata_port, SERDES_CR_ADDR, addr);
+ __combo_phy_reg_write(sata_port, SERDES_CR_DATA, data);
+ __combo_phy_reg_write(sata_port, SERDES_CR_CTL, CR_WR_RDN | CR_START);
+}
+
+static void highbank_cphy_disable_overrides(u8 sata_port)
+{
+ u8 lane = port_data[sata_port].lane_mapping;
+ u32 tmp;
+ if (unlikely(port_data[sata_port].phy_base == NULL))
+ return;
+ tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE);
+ tmp &= ~CPHY_SATA_OVERRIDE;
+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+}
+
+static void cphy_override_rx_mode(u8 sata_port, u32 val)
+{
+ u8 lane = port_data[sata_port].lane_mapping;
+ u32 tmp;
+ tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE);
+ tmp &= ~CPHY_SATA_OVERRIDE;
+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+
+ tmp |= CPHY_SATA_OVERRIDE;
+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+
+ tmp &= ~CPHY_SATA_DPLL_MODE;
+ tmp |= val << CPHY_SATA_DPLL_SHIFT;
+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+
+ tmp |= CPHY_SATA_DPLL_RESET;
+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+
+ tmp &= ~CPHY_SATA_DPLL_RESET;
+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+
+ msleep(15);
+}
+
+static void highbank_cphy_override_lane(u8 sata_port)
+{
+ u8 lane = port_data[sata_port].lane_mapping;
+ u32 tmp, k = 0;
+
+ if (unlikely(port_data[sata_port].phy_base == NULL))
+ return;
+ do {
+ tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS +
+ lane * SPHY_LANE);
+ } while ((tmp & SPHY_HALF_RATE) && (k++ < 1000));
+ cphy_override_rx_mode(sata_port, 3);
+}
+
+static int highbank_initialize_phys(struct device *dev, void __iomem *addr)
+{
+ struct device_node *sata_node = dev->of_node;
+ int phy_count = 0, phy, port = 0;
+ void __iomem *cphy_base[CPHY_PHY_COUNT];
+ struct device_node *phy_nodes[CPHY_PHY_COUNT];
+ memset(port_data, 0, sizeof(struct phy_lane_info) * CPHY_PORT_COUNT);
+ memset(phy_nodes, 0, sizeof(struct device_node*) * CPHY_PHY_COUNT);
+
+ do {
+ u32 tmp;
+ struct of_phandle_args phy_data;
+ if (of_parse_phandle_with_args(sata_node,
+ "calxeda,port-phys", "#phy-cells",
+ port, &phy_data))
+ break;
+ for (phy = 0; phy < phy_count; phy++) {
+ if (phy_nodes[phy] == phy_data.np)
+ break;
+ }
+ if (phy_nodes[phy] == NULL) {
+ phy_nodes[phy] = phy_data.np;
+ cphy_base[phy] = of_iomap(phy_nodes[phy], 0);
+ if (cphy_base[phy] == NULL) {
+ return 0;
+ }
+ phy_count += 1;
+ }
+ port_data[port].lane_mapping = phy_data.args[0];
+ of_property_read_u32(phy_nodes[phy], "phydev", &tmp);
+ port_data[port].phy_devs = tmp;
+ port_data[port].phy_base = cphy_base[phy];
+ of_node_put(phy_data.np);
+ port += 1;
+ } while (port < CPHY_PORT_COUNT);
+ return 0;
+}
+
+static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline)
+{
+ const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
+ struct ata_port *ap = link->ap;
+ struct ahci_port_priv *pp = ap->private_data;
+ u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
+ struct ata_taskfile tf;
+ bool online;
+ u32 sstatus;
+ int rc;
+ int retry = 10;
+
+ ahci_stop_engine(ap);
+
+ /* clear D2H reception area to properly wait for D2H FIS */
+ ata_tf_init(link->device, &tf);
+ tf.command = 0x80;
+ ata_tf_to_fis(&tf, 0, 0, d2h_fis);
+
+ do {
+ highbank_cphy_disable_overrides(link->ap->port_no);
+ rc = sata_link_hardreset(link, timing, deadline, &online, NULL);
+ highbank_cphy_override_lane(link->ap->port_no);
+
+ /* If the status is 1, we are connected, but the link did not
+ * come up. So retry resetting the link again.
+ */
+ if (sata_scr_read(link, SCR_STATUS, &sstatus))
+ break;
+ if (!(sstatus & 0x3))
+ break;
+ } while (!online && retry--);
+
+ ahci_start_engine(ap);
+
+ if (online)
+ *class = ahci_dev_classify(ap);
+
+ return rc;
+}
+
+static struct ata_port_operations ahci_highbank_ops = {
+ .inherits = &ahci_ops,
+ .hardreset = ahci_highbank_hardreset,
+};
+
+static const struct ata_port_info ahci_highbank_port_info = {
+ .flags = AHCI_FLAG_COMMON,
+ .pio_mask = ATA_PIO4,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_highbank_ops,
+};
+
+static struct scsi_host_template ahci_highbank_platform_sht = {
+ AHCI_SHT("highbank-ahci"),
+};
+
+static const struct of_device_id ahci_of_match[] = {
+ { .compatible = "calxeda,hb-ahci" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ahci_of_match);
+
+static int __init ahci_highbank_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ahci_host_priv *hpriv;
+ struct ata_host *host;
+ struct resource *mem;
+ int irq;
+ int n_ports;
+ int i;
+ int rc;
+ struct ata_port_info pi = ahci_highbank_port_info;
+ const struct ata_port_info *ppi[] = { &pi, NULL };
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(dev, "no mmio space\n");
+ return -EINVAL;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0) {
+ dev_err(dev, "no irq\n");
+ return -EINVAL;
+ }
+
+ hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!hpriv) {
+ dev_err(dev, "can't alloc ahci_host_priv\n");
+ return -ENOMEM;
+ }
+
+ hpriv->flags |= (unsigned long)pi.private_data;
+
+ hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
+ if (!hpriv->mmio) {
+ dev_err(dev, "can't map %pR\n", mem);
+ return -ENOMEM;
+ }
+
+ rc = highbank_initialize_phys(dev, hpriv->mmio);
+ if (rc)
+ return rc;
+
+
+ ahci_save_initial_config(dev, hpriv, 0, 0);
+
+ /* prepare host */
+ if (hpriv->cap & HOST_CAP_NCQ)
+ pi.flags |= ATA_FLAG_NCQ;
+
+ if (hpriv->cap & HOST_CAP_PMP)
+ pi.flags |= ATA_FLAG_PMP;
+
+ ahci_set_em_messages(hpriv, &pi);
+
+ /* CAP.NP sometimes indicate the index of the last enabled
+ * port, at other times, that of the last possible port, so
+ * determining the maximum port number requires looking at
+ * both CAP.NP and port_map.
+ */
+ n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
+
+ host = ata_host_alloc_pinfo(dev, ppi, n_ports);
+ if (!host) {
+ rc = -ENOMEM;
+ goto err0;
+ }
+
+ host->private_data = hpriv;
+
+ if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
+ host->flags |= ATA_HOST_PARALLEL_SCAN;
+
+ if (pi.flags & ATA_FLAG_EM)
+ ahci_reset_em(host);
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ ata_port_desc(ap, "mmio %pR", mem);
+ ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
+
+ /* set enclosure management message type */
+ if (ap->flags & ATA_FLAG_EM)
+ ap->em_message_type = hpriv->em_msg_type;
+
+ /* disabled/not-implemented port */
+ if (!(hpriv->port_map & (1 << i)))
+ ap->ops = &ata_dummy_port_ops;
+ }
+
+ rc = ahci_reset_controller(host);
+ if (rc)
+ goto err0;
+
+ ahci_init_controller(host);
+ ahci_print_info(host, "platform");
+
+ rc = ata_host_activate(host, irq, ahci_interrupt, 0,
+ &ahci_highbank_platform_sht);
+ if (rc)
+ goto err0;
+
+ return 0;
+err0:
+ return rc;
+}
+
+static int __devexit ahci_highbank_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ata_host *host = dev_get_drvdata(dev);
+
+ ata_host_detach(host);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ahci_highbank_suspend(struct device *dev)
+{
+ struct ata_host *host = dev_get_drvdata(dev);
+ struct ahci_host_priv *hpriv = host->private_data;
+ void __iomem *mmio = hpriv->mmio;
+ u32 ctl;
+ int rc;
+
+ if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
+ dev_err(dev, "firmware update required for suspend/resume\n");
+ return -EIO;
+ }
+
+ /*
+ * AHCI spec rev1.1 section 8.3.3:
+ * Software must disable interrupts prior to requesting a
+ * transition of the HBA to D3 state.
+ */
+ ctl = readl(mmio + HOST_CTL);
+ ctl &= ~HOST_IRQ_EN;
+ writel(ctl, mmio + HOST_CTL);
+ readl(mmio + HOST_CTL); /* flush */
+
+ rc = ata_host_suspend(host, PMSG_SUSPEND);
+ if (rc)
+ return rc;
+
+ return 0;
+}
+
+static int ahci_highbank_resume(struct device *dev)
+{
+ struct ata_host *host = dev_get_drvdata(dev);
+ int rc;
+
+ if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
+ rc = ahci_reset_controller(host);
+ if (rc)
+ return rc;
+
+ ahci_init_controller(host);
+ }
+
+ ata_host_resume(host);
+
+ return 0;
+}
+#endif
+
+SIMPLE_DEV_PM_OPS(ahci_highbank_pm_ops,
+ ahci_highbank_suspend, ahci_highbank_resume);
+
+static struct platform_driver ahci_highbank_driver = {
+ .remove = __devexit_p(ahci_highbank_remove),
+ .driver = {
+ .name = "highbank-ahci",
+ .owner = THIS_MODULE,
+ .of_match_table = ahci_of_match,
+ .pm = &ahci_highbank_pm_ops,
+ },
+ .probe = ahci_highbank_probe,
+};
+
+module_platform_driver(ahci_highbank_driver);
+
+MODULE_DESCRIPTION("Calxeda Highbank AHCI SATA platform driver");
+MODULE_AUTHOR("Mark Langsdorf <mark.langsdorf@calxeda.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("sata:highbank");

View File

@ -1,214 +0,0 @@
Fix a crash when block device is read and block size is changed at the same time
commit b87570f5d349661814b262dd5fc40787700f80d6
Author: Mikulas Patocka <mpatocka@redhat.com>
Date: Wed Sep 26 07:46:40 2012 +0200
Fix a crash when block device is read and block size is changed at the same time
The kernel may crash when block size is changed and I/O is issued
simultaneously.
Because some subsystems (udev or lvm) may read any block device anytime,
the bug actually puts any code that changes a block device size in
jeopardy.
The crash can be reproduced if you place "msleep(1000)" to
blkdev_get_blocks just before "bh->b_size = max_blocks <<
inode->i_blkbits;".
Then, run "dd if=/dev/ram0 of=/dev/null bs=4k count=1 iflag=direct"
While it is waiting in msleep, run "blockdev --setbsz 2048 /dev/ram0"
You get a BUG.
The direct and non-direct I/O is written with the assumption that block
size does not change. It doesn't seem practical to fix these crashes
one-by-one there may be many crash possibilities when block size changes
at a certain place and it is impossible to find them all and verify the
code.
This patch introduces a new rw-lock bd_block_size_semaphore. The lock is
taken for read during I/O. It is taken for write when changing block
size. Consequently, block size can't be changed while I/O is being
submitted.
For asynchronous I/O, the patch only prevents block size change while
the I/O is being submitted. The block size can change when the I/O is in
progress or when the I/O is being finished. This is acceptable because
there are no accesses to block size when asynchronous I/O is being
finished.
The patch prevents block size changing while the device is mapped with
mmap.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Index: linux-3.6.x86_64/drivers/char/raw.c
===================================================================
--- linux-3.6.x86_64.orig/drivers/char/raw.c 2012-11-16 17:12:35.127010280 -0500
+++ linux-3.6.x86_64/drivers/char/raw.c 2012-11-16 17:12:37.381002516 -0500
@@ -285,7 +285,7 @@
static const struct file_operations raw_fops = {
.read = do_sync_read,
- .aio_read = generic_file_aio_read,
+ .aio_read = blkdev_aio_read,
.write = do_sync_write,
.aio_write = blkdev_aio_write,
.fsync = blkdev_fsync,
Index: linux-3.6.x86_64/fs/block_dev.c
===================================================================
--- linux-3.6.x86_64.orig/fs/block_dev.c 2012-11-16 17:12:35.127010280 -0500
+++ linux-3.6.x86_64/fs/block_dev.c 2012-11-16 17:12:37.381002516 -0500
@@ -116,6 +116,8 @@
int set_blocksize(struct block_device *bdev, int size)
{
+ struct address_space *mapping;
+
/* Size must be a power of two, and between 512 and PAGE_SIZE */
if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size))
return -EINVAL;
@@ -124,6 +126,20 @@
if (size < bdev_logical_block_size(bdev))
return -EINVAL;
+ /* Prevent starting I/O or mapping the device */
+ down_write(&bdev->bd_block_size_semaphore);
+
+ /* Check that the block device is not memory mapped */
+ mapping = bdev->bd_inode->i_mapping;
+ mutex_lock(&mapping->i_mmap_mutex);
+ if (!prio_tree_empty(&mapping->i_mmap) ||
+ !list_empty(&mapping->i_mmap_nonlinear)) {
+ mutex_unlock(&mapping->i_mmap_mutex);
+ up_write(&bdev->bd_block_size_semaphore);
+ return -EBUSY;
+ }
+ mutex_unlock(&mapping->i_mmap_mutex);
+
/* Don't change the size if it is same as current */
if (bdev->bd_block_size != size) {
sync_blockdev(bdev);
@@ -131,6 +147,9 @@
bdev->bd_inode->i_blkbits = blksize_bits(size);
kill_bdev(bdev);
}
+
+ up_write(&bdev->bd_block_size_semaphore);
+
return 0;
}
@@ -472,6 +491,7 @@
inode_init_once(&ei->vfs_inode);
/* Initialize mutex for freeze. */
mutex_init(&bdev->bd_fsfreeze_mutex);
+ init_rwsem(&bdev->bd_block_size_semaphore);
}
static inline void __bd_forget(struct inode *inode)
@@ -1567,6 +1587,22 @@
return blkdev_ioctl(bdev, mode, cmd, arg);
}
+ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
+{
+ ssize_t ret;
+ struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host);
+
+ down_read(&bdev->bd_block_size_semaphore);
+
+ ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
+
+ up_read(&bdev->bd_block_size_semaphore);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(blkdev_aio_read);
+
/*
* Write data to the block device. Only intended for the block device itself
* and the raw driver which basically is a fake block device.
@@ -1578,12 +1614,16 @@
unsigned long nr_segs, loff_t pos)
{
struct file *file = iocb->ki_filp;
+ struct block_device *bdev = I_BDEV(file->f_mapping->host);
struct blk_plug plug;
ssize_t ret;
BUG_ON(iocb->ki_pos != pos);
blk_start_plug(&plug);
+
+ down_read(&bdev->bd_block_size_semaphore);
+
ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
if (ret > 0 || ret == -EIOCBQUEUED) {
ssize_t err;
@@ -1592,11 +1632,29 @@
if (err < 0 && ret > 0)
ret = err;
}
+
+ up_read(&bdev->bd_block_size_semaphore);
+
blk_finish_plug(&plug);
+
return ret;
}
EXPORT_SYMBOL_GPL(blkdev_aio_write);
+int blkdev_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ int ret;
+ struct block_device *bdev = I_BDEV(file->f_mapping->host);
+
+ down_read(&bdev->bd_block_size_semaphore);
+
+ ret = generic_file_mmap(file, vma);
+
+ up_read(&bdev->bd_block_size_semaphore);
+
+ return ret;
+}
+
/*
* Try to release a page associated with block device when the system
* is under memory pressure.
@@ -1627,9 +1685,9 @@
.llseek = block_llseek,
.read = do_sync_read,
.write = do_sync_write,
- .aio_read = generic_file_aio_read,
+ .aio_read = blkdev_aio_read,
.aio_write = blkdev_aio_write,
- .mmap = generic_file_mmap,
+ .mmap = blkdev_mmap,
.fsync = blkdev_fsync,
.unlocked_ioctl = block_ioctl,
#ifdef CONFIG_COMPAT
Index: linux-3.6.x86_64/include/linux/fs.h
===================================================================
--- linux-3.6.x86_64.orig/include/linux/fs.h 2012-11-16 17:12:35.127010280 -0500
+++ linux-3.6.x86_64/include/linux/fs.h 2012-11-16 17:12:37.424002387 -0500
@@ -724,6 +724,8 @@
int bd_fsfreeze_count;
/* Mutex for freeze */
struct mutex bd_fsfreeze_mutex;
+ /* A semaphore that prevents I/O while block size is being changed */
+ struct rw_semaphore bd_block_size_semaphore;
};
/*
@@ -2564,6 +2566,8 @@
unsigned long *nr_segs, size_t *count, int access_flags);
/* fs/block_dev.c */
+extern ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos);
extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos);
extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end,

View File

@ -1,290 +0,0 @@
blockdev: turn a rw semaphore into a percpu rw semaphore
commit 62ac665ff9fc07497ca524bd20d6a96893d11071
Author: Mikulas Patocka <mpatocka@redhat.com>
Date: Wed Sep 26 07:46:43 2012 +0200
blockdev: turn a rw semaphore into a percpu rw semaphore
This avoids cache line bouncing when many processes lock the semaphore
for read.
New percpu lock implementation
The lock consists of an array of percpu unsigned integers, a boolean
variable and a mutex.
When we take the lock for read, we enter rcu read section, check for a
"locked" variable. If it is false, we increase a percpu counter on the
current cpu and exit the rcu section. If "locked" is true, we exit the
rcu section, take the mutex and drop it (this waits until a writer
finished) and retry.
Unlocking for read just decreases percpu variable. Note that we can
unlock on a difference cpu than where we locked, in this case the
counter underflows. The sum of all percpu counters represents the number
of processes that hold the lock for read.
When we need to lock for write, we take the mutex, set "locked" variable
to true and synchronize rcu. Since RCU has been synchronized, no
processes can create new read locks. We wait until the sum of percpu
counters is zero - when it is, there are no readers in the critical
section.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Index: linux-3.6.x86_64/Documentation/percpu-rw-semaphore.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-3.6.x86_64/Documentation/percpu-rw-semaphore.txt 2012-11-16 17:12:57.351936583 -0500
@@ -0,0 +1,27 @@
+Percpu rw semaphores
+--------------------
+
+Percpu rw semaphores is a new read-write semaphore design that is
+optimized for locking for reading.
+
+The problem with traditional read-write semaphores is that when multiple
+cores take the lock for reading, the cache line containing the semaphore
+is bouncing between L1 caches of the cores, causing performance
+degradation.
+
+Locking for reading it very fast, it uses RCU and it avoids any atomic
+instruction in the lock and unlock path. On the other hand, locking for
+writing is very expensive, it calls synchronize_rcu() that can take
+hundreds of microseconds.
+
+The lock is declared with "struct percpu_rw_semaphore" type.
+The lock is initialized percpu_init_rwsem, it returns 0 on success and
+-ENOMEM on allocation failure.
+The lock must be freed with percpu_free_rwsem to avoid memory leak.
+
+The lock is locked for read with percpu_down_read, percpu_up_read and
+for write with percpu_down_write, percpu_up_write.
+
+The idea of using RCU for optimized rw-lock was introduced by
+Eric Dumazet <eric.dumazet@gmail.com>.
+The code was written by Mikulas Patocka <mpatocka@redhat.com>
Index: linux-3.6.x86_64/fs/block_dev.c
===================================================================
--- linux-3.6.x86_64.orig/fs/block_dev.c 2012-11-16 17:12:37.381002516 -0500
+++ linux-3.6.x86_64/fs/block_dev.c 2012-11-16 17:27:41.217005828 -0500
@@ -127,7 +127,7 @@
return -EINVAL;
/* Prevent starting I/O or mapping the device */
- down_write(&bdev->bd_block_size_semaphore);
+ percpu_down_write(&bdev->bd_block_size_semaphore);
/* Check that the block device is not memory mapped */
mapping = bdev->bd_inode->i_mapping;
@@ -135,7 +135,7 @@
if (!prio_tree_empty(&mapping->i_mmap) ||
!list_empty(&mapping->i_mmap_nonlinear)) {
mutex_unlock(&mapping->i_mmap_mutex);
- up_write(&bdev->bd_block_size_semaphore);
+ percpu_up_write(&bdev->bd_block_size_semaphore);
return -EBUSY;
}
mutex_unlock(&mapping->i_mmap_mutex);
@@ -148,7 +148,7 @@
kill_bdev(bdev);
}
- up_write(&bdev->bd_block_size_semaphore);
+ percpu_up_write(&bdev->bd_block_size_semaphore);
return 0;
}
@@ -460,6 +460,12 @@
struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL);
if (!ei)
return NULL;
+
+ if (unlikely(percpu_init_rwsem(&ei->bdev.bd_block_size_semaphore))) {
+ kmem_cache_free(bdev_cachep, ei);
+ return NULL;
+ }
+
return &ei->vfs_inode;
}
@@ -468,6 +474,8 @@
struct inode *inode = container_of(head, struct inode, i_rcu);
struct bdev_inode *bdi = BDEV_I(inode);
+ percpu_free_rwsem(&bdi->bdev.bd_block_size_semaphore);
+
kmem_cache_free(bdev_cachep, bdi);
}
@@ -491,7 +499,6 @@
inode_init_once(&ei->vfs_inode);
/* Initialize mutex for freeze. */
mutex_init(&bdev->bd_fsfreeze_mutex);
- init_rwsem(&bdev->bd_block_size_semaphore);
}
static inline void __bd_forget(struct inode *inode)
@@ -1593,11 +1600,11 @@
ssize_t ret;
struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host);
- down_read(&bdev->bd_block_size_semaphore);
+ percpu_down_read(&bdev->bd_block_size_semaphore);
ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
- up_read(&bdev->bd_block_size_semaphore);
+ percpu_up_read(&bdev->bd_block_size_semaphore);
return ret;
}
@@ -1622,7 +1629,7 @@
blk_start_plug(&plug);
- down_read(&bdev->bd_block_size_semaphore);
+ percpu_down_read(&bdev->bd_block_size_semaphore);
ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
if (ret > 0 || ret == -EIOCBQUEUED) {
@@ -1633,7 +1640,7 @@
ret = err;
}
- up_read(&bdev->bd_block_size_semaphore);
+ percpu_up_read(&bdev->bd_block_size_semaphore);
blk_finish_plug(&plug);
@@ -1646,11 +1653,11 @@
int ret;
struct block_device *bdev = I_BDEV(file->f_mapping->host);
- down_read(&bdev->bd_block_size_semaphore);
+ percpu_down_read(&bdev->bd_block_size_semaphore);
ret = generic_file_mmap(file, vma);
- up_read(&bdev->bd_block_size_semaphore);
+ percpu_up_read(&bdev->bd_block_size_semaphore);
return ret;
}
Index: linux-3.6.x86_64/include/linux/fs.h
===================================================================
--- linux-3.6.x86_64.orig/include/linux/fs.h 2012-11-16 17:12:37.424002387 -0500
+++ linux-3.6.x86_64/include/linux/fs.h 2012-11-16 17:28:12.578901349 -0500
@@ -415,6 +415,7 @@
#include <linux/migrate_mode.h>
#include <linux/uidgid.h>
#include <linux/lockdep.h>
+#include <linux/percpu-rwsem.h>
#include <asm/byteorder.h>
@@ -725,7 +726,7 @@
/* Mutex for freeze */
struct mutex bd_fsfreeze_mutex;
/* A semaphore that prevents I/O while block size is being changed */
- struct rw_semaphore bd_block_size_semaphore;
+ struct percpu_rw_semaphore bd_block_size_semaphore;
};
/*
Index: linux-3.6.x86_64/include/linux/percpu-rwsem.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-3.6.x86_64/include/linux/percpu-rwsem.h 2012-11-16 17:12:57.354936574 -0500
@@ -0,0 +1,89 @@
+#ifndef _LINUX_PERCPU_RWSEM_H
+#define _LINUX_PERCPU_RWSEM_H
+
+#include <linux/mutex.h>
+#include <linux/percpu.h>
+#include <linux/rcupdate.h>
+#include <linux/delay.h>
+
+struct percpu_rw_semaphore {
+ unsigned __percpu *counters;
+ bool locked;
+ struct mutex mtx;
+};
+
+static inline void percpu_down_read(struct percpu_rw_semaphore *p)
+{
+ rcu_read_lock();
+ if (unlikely(p->locked)) {
+ rcu_read_unlock();
+ mutex_lock(&p->mtx);
+ this_cpu_inc(*p->counters);
+ mutex_unlock(&p->mtx);
+ return;
+ }
+ this_cpu_inc(*p->counters);
+ rcu_read_unlock();
+}
+
+static inline void percpu_up_read(struct percpu_rw_semaphore *p)
+{
+ /*
+ * On X86, write operation in this_cpu_dec serves as a memory unlock
+ * barrier (i.e. memory accesses may be moved before the write, but
+ * no memory accesses are moved past the write).
+ * On other architectures this may not be the case, so we need smp_mb()
+ * there.
+ */
+#if defined(CONFIG_X86) && (!defined(CONFIG_X86_PPRO_FENCE) && !defined(CONFIG_X86_OOSTORE))
+ barrier();
+#else
+ smp_mb();
+#endif
+ this_cpu_dec(*p->counters);
+}
+
+static inline unsigned __percpu_count(unsigned __percpu *counters)
+{
+ unsigned total = 0;
+ int cpu;
+
+ for_each_possible_cpu(cpu)
+ total += ACCESS_ONCE(*per_cpu_ptr(counters, cpu));
+
+ return total;
+}
+
+static inline void percpu_down_write(struct percpu_rw_semaphore *p)
+{
+ mutex_lock(&p->mtx);
+ p->locked = true;
+ synchronize_rcu();
+ while (__percpu_count(p->counters))
+ msleep(1);
+ smp_rmb(); /* paired with smp_mb() in percpu_sem_up_read() */
+}
+
+static inline void percpu_up_write(struct percpu_rw_semaphore *p)
+{
+ p->locked = false;
+ mutex_unlock(&p->mtx);
+}
+
+static inline int percpu_init_rwsem(struct percpu_rw_semaphore *p)
+{
+ p->counters = alloc_percpu(unsigned);
+ if (unlikely(!p->counters))
+ return -ENOMEM;
+ p->locked = false;
+ mutex_init(&p->mtx);
+ return 0;
+}
+
+static inline void percpu_free_rwsem(struct percpu_rw_semaphore *p)
+{
+ free_percpu(p->counters);
+ p->counters = NULL; /* catch use after free bugs */
+}
+
+#endif

View File

@ -12,6 +12,7 @@ CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
CONFIG_VFP=y
CONFIG_ARM_UNWIND=y
# CONFIG_ARCH_MULTI_V7 is not set
CONFIG_SMP=y
CONFIG_NR_CPUS=4
@ -27,6 +28,7 @@ CONFIG_FPE_FASTFPE=y
CONFIG_HIGHPTE=y
CONFIG_HW_PERF_EVENTS=y
CONFIG_UACCESS_WITH_MEMCPY=y
# CONFIG_GENERIC_CPUFREQ_CPU0 is not set
# Generic ARM Errata
CONFIG_ARM_ERRATA_720789=y
@ -42,6 +44,7 @@ CONFIG_ZBOOT_ROM_TEXT=0
CONFIG_ZBOOT_ROM_BSS=0
CONFIG_LOCAL_TIMERS=y
CONFIG_ATAGS=y
CONFIG_ATAGS_PROC=y
CONFIG_PL330_DMA=y
@ -63,9 +66,6 @@ CONFIG_CPU_IDLE=y
# CONFIG_CPU_IDLE_GOV_LADDER is not set
CONFIG_CPU_IDLE_GOV_MENU=y
CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
CONFIG_LSM_MMAP_MIN_ADDR=32768
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
@ -75,6 +75,16 @@ CONFIG_SUSPEND=y
CONFIG_ARM_CPU_SUSPEND=y
CONFIG_ARM_CPU_TOPOLOGY=y
CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
CONFIG_LSM_MMAP_MIN_ADDR=32768
# CONFIG_XEN is not set
CONFIG_PINCTRL=y
CONFIG_PINCONF=y
CONFIG_COMMON_CLK=y
CONFIG_THERMAL=y
CONFIG_ETHERNET=y
@ -84,20 +94,17 @@ CONFIG_PERF_COUNTERS=y
CONFIG_CC_STACKPROTECTOR=y
CONFIG_AUTO_ZRELADDR=y
CONFIG_SECCOMP=y
CONFIG_STRICT_DEVMEM=y
CONFIG_SPARSE_IRQ=y
# Generic HW for all ARM platforms
CONFIG_LEDS=y
CONFIG_LEDS_CPU=y
CONFIG_LEDS_GPIO=m
CONFIG_LBDAF=y
CONFIG_GPIOLIB=y
CONFIG_RFKILL_GPIO=m
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIO_GENERIC_PLATFORM=m
@ -135,10 +142,13 @@ CONFIG_MMC_SPI=m
CONFIG_MMC_DW=m
CONFIG_MMC_DW_PLTFM=m
CONFIG_MMC_DW_PCI=m
# CONFIG_MMC_DW_EXYNOS is not set
# CONFIG_MMC_DW_IDMAC is not set
CONFIG_MMC_SDHCI_PXAV3=m
CONFIG_MMC_SDHCI_PXAV2=m
# CONFIG_DW_DMAC_BIG_ENDIAN_IO is not set
# Generic GPIO options
CONFIG_GENERIC_GPIO=y
@ -233,12 +243,15 @@ CONFIG_UBIFS_FS_ZLIB=y
# CONFIG_UBIFS_FS_DEBUG is not set
# HW crypto and rng
CONFIG_CRYPTO_SHA1_ARM=m
CONFIG_CRYPTO_AES_ARM=m
CONFIG_HW_RANDOM_ATMEL=m
CONFIG_HW_RANDOM_EXYNOS=m
# Device tree
CONFIG_OF=y
CONFIG_USE_OF=y
CONFIG_OF_IRQ=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
CONFIG_ARM_APPENDED_DTB=y
CONFIG_PROC_DEVICETREE=y
@ -251,6 +264,7 @@ CONFIG_OF_PCI_IRQ=y
CONFIG_I2C_MUX_PINCTRL=m
CONFIG_OF_MDIO=m
CONFIG_MDIO_BUS_MUX_GPIO=m
CONFIG_MDIO_BUS_MUX_MMIOREG=m
CONFIG_BPF_JIT=y
@ -262,6 +276,7 @@ CONFIG_EDAC_LEGACY_SYSFS=y
CONFIG_RTC_DRV_88PM80X=m
CONFIG_RTC_DRV_PL030=m
CONFIG_RTC_DRV_PL031=m
CONFIG_RTC_DRV_SNVS=m
CONFIG_RFKILL_REGULATOR=m
CONFIG_INPUT_88PM80X_ONKEY=y
CONFIG_INPUT_GP2A=m
@ -271,14 +286,22 @@ CONFIG_SERIAL_AMBA_PL010=m
CONFIG_SERIAL_AMBA_PL011=m
CONFIG_GPIO_PL061=y
CONFIG_GPIO_MCP23S08=m
CONFIG_GPIO_ADNP=m
CONFIG_PL310_ERRATA_753970=y
CONFIG_MFD_88PM800=m
CONFIG_MFD_88PM805=m
CONFIG_MFD_SYSCON=y
# CONFIG_MFD_SMSC is not set
# CONFIG_MFD_DA9055 is not set
# CONFIG_MFD_MAX8907 is not set
CONFIG_REGULATOR_VIRTUAL_CONSUMER=m
CONFIG_REGULATOR_USERSPACE_CONSUMER=m
CONFIG_REGULATOR_GPIO=m
CONFIG_REGULATOR_AD5398=m
CONFIG_REGULATOR_ANATOP=m
CONFIG_REGULATOR_FAN53555=m
CONFIG_REGULATOR_ISL6271A=m
CONFIG_REGULATOR_MAX1586=m
CONFIG_REGULATOR_MAX8649=m
@ -291,6 +314,12 @@ CONFIG_REGULATOR_TPS6507X=m
CONFIG_CHARGER_MANAGER=y
CONFIG_EXTCON_GPIO=m
# CONFIG_ARM_VIRT_EXT is not set
# CONFIG_PINCTRL_EXYNOS4 is not set
# CONFIG_AUTO_ZRELADDR is not set
# CONFIG_ASYMMETRIC_KEY_TYPE is not set
# CONFIG_VFIO is not set
# CONFIG_XIP_KERNEL is not set
@ -355,3 +384,4 @@ CONFIG_EXTCON_GPIO=m
# CONFIG_NET_VENDOR_CIRRUS is not set
# CONFIG_CS89x0 is not set
# CONFIG_DVB_USB_PCTV452E is not set

View File

@ -59,4 +59,7 @@ CONFIG_OC_ETM=y
# CONFIG_MEDIA_SUPPORT is not set
# CONFIG_DRM is not set
# CONFIG_SND is not set
# CONFIG_ARCH_MULTI_V4 is not set
# CONFIG_ARCH_MULTI_V4T is not set
# CONFIG_ARCH_MULTI_V6 is not set
# end of list of requested disabled options

View File

@ -7,6 +7,7 @@ CONFIG_NEON=y
# CONFIG_THUMB2_KERNEL is not set
CONFIG_CPU_FREQ_IMX=y
CONFIG_SOC_IMX53=y
CONFIG_SOC_IMX6Q=y
CONFIG_MACH_ARMADILLO5X0=y
@ -67,6 +68,7 @@ CONFIG_I2C_IMX=m
CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_GPIO_MCP23S08=m
# CONFIG_GPIO_MC9S08DZ60 is not set
CONFIG_PINCTRL_IMX35=y
CONFIG_PINCTRL_IMX51=y
CONFIG_PINCTRL_IMX53=y
CONFIG_USB_EHCI_MXC=y
@ -77,6 +79,12 @@ CONFIG_MMC_MXC=m
CONFIG_RTC_MXC=y
CONFIG_RTC_DRV_MXC=m
CONFIG_DRM_IMX=m
CONFIG_DRM_IMX_FB_HELPER=m
CONFIG_DRM_IMX_PARALLEL_DISPLAY=m
CONFIG_DRM_IMX_IPUV3_CORE=m
CONFIG_DRM_IMX_IPUV3=m
CONFIG_VIDEO_CODA=m
CONFIG_BACKLIGHT_PWM=m
CONFIG_LEDS_PWM=m
@ -104,6 +112,8 @@ CONFIG_SND_SOC_IMX_SGTL5000=m
CONFIG_PL310_ERRATA_769419=y
CONFIG_LEDS_RENESAS_TPU=y
CONFIG_MFD_MAX8907=m
CONFIG_FB_IMX=m
# CONFIG_NET_VENDOR_BROADCOM is not set

View File

@ -6,6 +6,7 @@ CONFIG_ARCH_KIRKWOOD_DT=y
CONFIG_MACH_D2NET_V2=y
CONFIG_MACH_DB88F6281_BP=y
CONFIG_MACH_DOCKSTAR=y
CONFIG_MACH_DOCKSTAR_DT=y
CONFIG_MACH_DREAMPLUG_DT=y
CONFIG_MACH_ESATA_SHEEVAPLUG=y
CONFIG_MACH_DLINK_KIRKWOOD_DT=y
@ -14,6 +15,8 @@ CONFIG_MACH_GURUPLUG=y
CONFIG_MACH_ICONNECT_DT=y
CONFIG_MACH_IB62X0_DT=y
CONFIG_MACH_INETSPACE_V2=y
CONFIG_MACH_IOMEGA_IX2_200_DT=y
CONFIG_MACH_KM_KIRKWOOD_DT=y
CONFIG_MACH_LSXL_DT=y
CONFIG_MACH_MV88F6281GTW_GE=y
CONFIG_MACH_NETSPACE_V2=y
@ -48,6 +51,8 @@ CONFIG_LEDS_NETXBIG=m
CONFIG_RTC_DRV_MV=y
CONFIG_MV_XOR=y
CONFIG_CRYPTO_DEV_MV_CESA=m
CONFIG_PINCTRL_MVEBU=y
CONFIG_PINCTRL_KIRKWOOD=y
# CONFIG_CPU_FEROCEON_OLD_ID is not set
# CONFIG_INPUT_GP2A is not set

View File

@ -153,7 +153,6 @@ CONFIG_WL_TI=y
CONFIG_WLCORE_SDIO=m
CONFIG_TI_ST=m
# CONFIG_TI_CPSW is not set
CONFIG_GPIOLIB=y
CONFIG_MTD_NAND_OMAP2=y
CONFIG_MTD_NAND_OMAP_PREFETCH=y
CONFIG_MTD_NAND_OMAP_PREFETCH_DMA=y
@ -177,6 +176,7 @@ CONFIG_TWL4030_POWER=y
CONFIG_TWL4030_CODEC=y
CONFIG_TWL4030_WATCHDOG=m
CONFIG_GPIO_TWL4030=m
CONFIG_GPIO_TWL6040=m
CONFIG_CHARGER_TWL4030=m
CONFIG_TWL6030_PWM=m
CONFIG_TWL6040_CORE=y
@ -186,19 +186,23 @@ CONFIG_TI_DAVINCI_MDIO=m
CONFIG_TI_DAVINCI_CPDMA=m
CONFIG_LEDS_PWM=m
CONFIG_LEDS_LP8788=m
CONFIG_MTD_ONENAND_OMAP2=y
CONFIG_HDQ_MASTER_OMAP=m
CONFIG_I2C_OMAP=y
CONFIG_I2C_OMAP=m
CONFIG_SPI_OMAP24XX=y
CONFIG_MFD_OMAP_USB_HOST=y
CONFIG_MFD_WL1273_CORE=m
CONFIG_MFD_LP8788=y
CONFIG_REGULATOR_TWL4030=y
CONFIG_REGULATOR_LP8788=y
# Enable V4L2 drivers for OMAP2+
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_VIDEO_VPFE_CAPTURE=m
CONFIG_VIDEO_OMAP2_VOUT=m
CONFIG_VIDEO_DM6446_CCDC=m
# CONFIG_VIDEO_OMAP3 is not set
# Also enable vivi driver - useful for testing a full kernelspace V4L2 driver
CONFIG_V4L_TEST_DRIVERS=y
@ -227,11 +231,10 @@ CONFIG_OMAP2_DSS_DSI=y
CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
CONFIG_OMAP2_DSS_SLEEP_BEFORE_RESET=y
CONFIG_OMAP2_DSS_SLEEP_AFTER_VENC_RESET=y
CONFIG_VIDEO_DM6446_CCDC=m
CONFIG_PANEL_TFP410=m
CONFIG_PANEL_PICODLP=m
CONFIG_PANEL_TAAL=m
CONFIG_PANEL_PICODLP=m
CONFIG_BACKLIGHT_PANDORA=m
#
@ -243,21 +246,22 @@ CONFIG_PANEL_NEC_NL8048HL11_01B=y
CONFIG_PANEL_TPO_TD043MTEA1=y
CONFIG_SND_OMAP_SOC=y
CONFIG_SND_OMAP_SOC_MCBSP=y
CONFIG_SND_OMAP_SOC_MCPDM=y
CONFIG_SND_OMAP_SOC_OVERO=y
CONFIG_SND_OMAP_SOC_OMAP3EVM=y
CONFIG_SND_OMAP_SOC_AM3517EVM=y
CONFIG_SND_OMAP_SOC_SDP3430=y
CONFIG_SND_OMAP_SOC_SDP4430=y
CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=y
CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE=y
CONFIG_SND_OMAP_SOC_ZOOM2=y
CONFIG_SND_OMAP_SOC_MCBSP=m
CONFIG_SND_OMAP_SOC_MCPDM=m
CONFIG_SND_OMAP_SOC_OVERO=m
CONFIG_SND_OMAP_SOC_OMAP3EVM=m
CONFIG_SND_OMAP_SOC_AM3517EVM=m
CONFIG_SND_OMAP_SOC_SDP3430=m
CONFIG_SND_OMAP_SOC_SDP4430=m
CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m
CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE=m
CONFIG_SND_OMAP_SOC_ZOOM2=m
CONFIG_SND_OMAP_SOC_IGEP0020=y
CONFIG_SND_OMAP_SOC_OMAP_HDMI=y
# Because alsa is modular http://www.spinics.net/lists/linux-omap/msg67307.html
# CONFIG_SND_OMAP_SOC_OMAP4_HDMI is not set
CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040=m
CONFIG_SND_OMAP_SOC_OMAP_TWL4030=m
CONFIG_SND_SOC_I2C_AND_SPI=y
# CONFIG_SND_OMAP_SOC_RX51 is not set
# CONFIG_SND_SOC_ALL_CODECS is not set
@ -295,19 +299,21 @@ CONFIG_TWL4030_USB=y
CONFIG_TWL6030_USB=y
CONFIG_RTC_DRV_TWL4030=y
CONFIG_TIDSPBRIDGE=m
CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE=0x600000
CONFIG_IR_RX51=m
# CONFIG_TIDSPBRIDGE is not set
# CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE=0x600000
# CONFIG_TIDSPBRIDGE_DEBUG is not set
CONFIG_TIDSPBRIDGE_RECOVERY=y
# CONFIG_TIDSPBRIDGE_RECOVERY=y
# CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK is not set
CONFIG_TIDSPBRIDGE_WDT3=y
CONFIG_TIDSPBRIDGE_WDT_TIMEOUT=5
# CONFIG_TIDSPBRIDGE_WDT3=y
# CONFIG_TIDSPBRIDGE_WDT_TIMEOUT=5
# CONFIG_TIDSPBRIDGE_NTFY_PWRERR is not set
# CONFIG_TIDSPBRIDGE_BACKTRACE is not set
CONFIG_OMAP_REMOTEPROC=m
CONFIG_OMAP_BANDGAP=m
CONFIG_OMAP_IOVMM=m
# CONFIG_OMAP_REMOTEPROC is not set
# CONFIG_OMAP_BANDGAP is not set
# CONFIG_OMAP_IOVMM is not set
CONFIG_CRYPTO_DEV_OMAP_SHAM=m
CONFIG_CRYPTO_DEV_OMAP_AES=m

View File

@ -18,13 +18,12 @@ CONFIG_MACH_WARIO=y
CONFIG_MACH_VENTANA=y
CONFIG_TEGRA_DEBUG_UARTD=y
CONFIG_NR_CPUS=4
CONFIG_ARM_CPU_TOPOLOGY=y
CONFIG_TEGRA_IOMMU_GART=y
CONFIG_TEGRA_IOMMU_SMMU=y
CONFIG_I2C_TEGRA=y
CONFIG_I2C_TEGRA=m
# This block is temporary until we work out why the MMC modules don't work as modules
CONFIG_MMC=y

View File

@ -93,3 +93,10 @@ CONFIG_PATA_PLATFORM=m
CONFIG_PATA_OF_PLATFORM=m
# CONFIG_NET_VENDOR_BROADCOM is not set
# unset on versatille for jon masters
# CONFIG_GPIOLIB is not set
# CONFIG_ARCH_MULTI_V4 is not set
# CONFIG_ARCH_MULTI_V4T is not set
# CONFIG_ARCH_MULTI_V6 is not set
# CONFIG_DRM_EXYNOS is not set

View File

@ -191,49 +191,76 @@ CONFIG_EXTRA_FIRMWARE=""
#
CONFIG_MTD=m
# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
#
# User Modules And Translation Layers
#
# CONFIG_MTD_CHAR is not set
CONFIG_MTD_BLKDEVS=m
CONFIG_MTD_BLOCK=m
# CONFIG_MTD_BLOCK_RO is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
# CONFIG_SM_FTL is not set
# CONFIG_MTD_OOPS is not set
# CONFIG_MTD_SWAP is not set
#
# RAM/ROM/Flash chip drivers
#
# CONFIG_MTD_CFI is not set
# CONFIG_MTD_JEDECPROBE is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_TS5500 is not set
# CONFIG_MTD_INTEL_VR_NOR is not set
# CONFIG_MTD_PLATRAM is not set
# Self-contained MTD device drivers
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_SLRAM is not set
CONFIG_MTD_PHRAM=m
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLOCK2MTD is not set
#
# Disk-On-Chip Device Drivers
#
# CONFIG_MTD_DOCG3 is not set
# CONFIG_MTD_NAND is not set
# CONFIG_MTD_ONENAND is not set
# CONFIG_MTD_NAND_VERIFY_WRITE is not set
# CONFIG_MTD_NAND_ECC_BCH is not set
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_LPDDR is not set
# CONFIG_SM_FTL is not set
# CONFIG_MTD_TS5500 is not set
# CONFIG_MTD_INTEL_VR_NOR is not set
# CONFIG_MTD_PLATRAM is not set
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_AR7_PARTS is not set
# CONFIG_MTD_SLRAM is not set
CONFIG_MTD_PHRAM=m
# CONFIG_MTD_NAND is not set
# CONFIG_MTD_ONENAND is not set
#
CONFIG_MTD_UBI=m
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTD_UBI_BEB_RESERVE=2
CONFIG_MTD_UBI_BEB_LIMIT=20
# CONFIG_MTD_UBI_FASTMAP is not set
CONFIG_MTD_UBI_GLUEBI=m
#
# Parallel port support
#
@ -452,6 +479,7 @@ CONFIG_ATA_BMDMA=y
CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_ATA_SFF=y
CONFIG_ATA_PIIX=y
# CONFIG_SATA_HIGHBANK is not set
CONFIG_ATA_ACPI=y
CONFIG_BLK_DEV_SX8=m
CONFIG_PDC_ADMA=m
@ -472,7 +500,6 @@ CONFIG_SATA_ULI=m
CONFIG_SATA_VIA=m
CONFIG_SATA_VITESSE=m
CONFIG_SATA_ACARD_AHCI=m
# CONFIG_SATA_HIGHBANK is not set
# CONFIG_PATA_LEGACY is not set
CONFIG_PATA_ACPI=m
@ -623,6 +650,7 @@ CONFIG_TCP_MD5SIG=y
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_DIAG is not set
CONFIG_UNIX=y
CONFIG_UNIX_DIAG=m
CONFIG_NET_KEY=m
@ -702,6 +730,7 @@ CONFIG_IPV6_MIP6=y
CONFIG_IPV6_SIT=m
CONFIG_IPV6_SIT_6RD=y
CONFIG_IPV6_TUNNEL=m
# CONFIG_IPV6_GRE is not set
CONFIG_IPV6_SUBTREES=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_MROUTE=y
@ -845,7 +874,6 @@ CONFIG_IP_NF_MATCH_ECN=m
CONFIG_IP_NF_MATCH_RPFILTER=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_ECN=m
@ -853,6 +881,8 @@ CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_REJECT=y
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_NF_NAT_IPV4=m
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
@ -884,6 +914,9 @@ CONFIG_IP6_NF_SECURITY=m
CONFIG_IP6_NF_TARGET_LOG=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_TARGET_HL=m
CONFIG_NF_NAT_IPV6=m
# CONFIG_IP6_NF_TARGET_MASQUERADE is not set
# CONFIG_IP6_NF_TARGET_NPT is not set
#
# Bridge: Netfilter Configuration
@ -1073,6 +1106,7 @@ CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_MACVLAN=m
CONFIG_MACVTAP=m
CONFIG_VXLAN=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
CONFIG_VETH=m
@ -1325,6 +1359,7 @@ CONFIG_NET_VENDOR_XIRCOM=y
CONFIG_PCMCIA_XIRC2PS=m
CONFIG_PHYLIB=y
CONFIG_AT803X_PHY=m
CONFIG_AMD_PHY=m
CONFIG_BROADCOM_PHY=m
CONFIG_BCM87XX_PHY=m
@ -1380,6 +1415,7 @@ CONFIG_MLX4_EN_DCB=y
CONFIG_SFC=m
CONFIG_SFC_MCDI_MON=y
CONFIG_SFC_SRIOV=y
CONFIG_SFC_PTP=y
# CONFIG_SFC_MTD is not set
@ -1494,6 +1530,7 @@ CONFIG_BRCMFMAC=m
CONFIG_BRCMFMAC_SDIO=y
CONFIG_BRCMFMAC_SDIO_OOB=y
CONFIG_BRCMFMAC_USB=y
# CONFIG_BRCMISCAN is not set
# CONFIG_BRCMDBG is not set
CONFIG_HERMES=m
CONFIG_HERMES_CACHE_FW_ON_INIT=y
@ -2049,6 +2086,7 @@ CONFIG_TIFM_CORE=m
CONFIG_TIFM_7XX1=m
CONFIG_TCG_TPM=m
CONFIG_TCG_TIS=m
# CONFIG_TCG_TIS_I2C_INFINEON is not set
CONFIG_TCG_NSC=m
CONFIG_TCG_ATMEL=m
# CONFIG_TCG_INFINEON is not set
@ -2075,6 +2113,7 @@ CONFIG_CYCLADES=m
# CONFIG_ISI is not set
# CONFIG_RIO is not set
CONFIG_SERIAL_JSM=m
# CONFIG_SERIAL_SCCNXP is not set
# CONFIG_SERIAL_MFD_HSU is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
@ -2083,6 +2122,7 @@ CONFIG_SERIAL_JSM=m
#
# Non-8250 serial port support
#
# CONFIG_SERIAL_KGDB_NMI is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_XILINX_PS_UART is not set
@ -2171,6 +2211,7 @@ CONFIG_SENSORS_ADM1026=m
CONFIG_SENSORS_ADM1029=m
CONFIG_SENSORS_ADM1031=m
CONFIG_SENSORS_ADM9240=m
CONFIG_SENSORS_ADT7410=m
CONFIG_SENSORS_ADS7828=m
CONFIG_SENSORS_ADT7462=m
CONFIG_SENSORS_ADT7470=m
@ -2290,6 +2331,7 @@ CONFIG_SENSORS_LTC2978=m
CONFIG_SENSORS_MAX34440=m
CONFIG_SENSORS_MAX8688=m
CONFIG_SENSORS_MAX1668=m
CONFIG_SENSORS_MAX197=m
# CONFIG_HMC6352 is not set
# CONFIG_BMP085 is not set
@ -2304,6 +2346,7 @@ CONFIG_W1_CON=y
CONFIG_W1_MASTER_DS2490=m
CONFIG_W1_MASTER_DS2482=m
CONFIG_W1_MASTER_DS1WM=m
# CONFIG_HDQ_MASTER_OMAP is not set
CONFIG_W1_SLAVE_THERM=m
CONFIG_W1_SLAVE_SMEM=m
CONFIG_W1_SLAVE_DS2408=m
@ -2375,6 +2418,7 @@ CONFIG_W83697UG_WDT=m
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_TIMERIOMEM=m
CONFIG_HW_RANDOM_TPM=m
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
# CONFIG_RTC_DEBUG is not set
@ -2408,6 +2452,7 @@ CONFIG_RTC_DRV_RS5C372=m
# CONFIG_RTC_DRV_TEST is not set
CONFIG_RTC_DRV_X1205=m
CONFIG_RTC_DRV_V3020=m
CONFIG_RTC_DRV_DS2404=m
CONFIG_RTC_DRV_STK17TA8=m
# CONFIG_RTC_DRV_S35390A is not set
CONFIG_RTC_DRV_RX8581=m
@ -2450,7 +2495,7 @@ CONFIG_VGA_ARB_MAX_GPUS=16
CONFIG_DRM=m
CONFIG_DRM_LOAD_EDID_FIRMWARE=y
# CONFIG_DRM_AST is not set # do not enable on f17 or older
# CONFIG_DRM_AST is not set # do not enable on f17 or older
# CONFIG_DRM_CIRRUS_QEMU is not set # do not enable on f17 or older
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not set
@ -2465,6 +2510,8 @@ CONFIG_DRM_I915=m
CONFIG_DRM_I915_KMS=y
CONFIG_DRM_VIA=m
CONFIG_DRM_NOUVEAU=m
CONFIG_NOUVEAU_DEBUG=5
CONFIG_NOUVEAU_DEBUG_DEFAULT=3
CONFIG_DRM_NOUVEAU_BACKLIGHT=y
CONFIG_DRM_NOUVEAU_DEBUG=y
# CONFIG_DRM_PSB is not set
@ -2488,6 +2535,8 @@ CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=8192
CONFIG_HANGCHECK_TIMER=m
CONFIG_MEDIA_USB_SUPPORT=y
CONFIG_MEDIA_PCI_SUPPORT=y
#
# Multimedia devices
#
@ -2545,6 +2594,7 @@ CONFIG_VIDEO_CX231XX_RC=y
CONFIG_VIDEO_HEXIUM_ORION=m
CONFIG_VIDEO_HEXIUM_GEMINI=m
CONFIG_VIDEO_IVTV=m
# CONFIG_VIDEO_IVTV_ALSA is not set
CONFIG_VIDEO_MEYE=m
CONFIG_VIDEO_MXB=m
CONFIG_VIDEO_PVRUSB2_DVB=y
@ -2556,6 +2606,8 @@ CONFIG_VIDEO_SAA7134_ALSA=m
CONFIG_VIDEO_SAA7134_DVB=m
CONFIG_VIDEO_SAA7134_RC=y
CONFIG_VIDEO_USBVISION=m
CONFIG_VIDEO_STK1160=m
CONFIG_VIDEO_STK1160_AC97=y
CONFIG_VIDEO_W9966=m
CONFIG_VIDEO_ZORAN=m
CONFIG_VIDEO_ZORAN_AVS6EYES=m
@ -2619,6 +2671,7 @@ CONFIG_DVB_BT8XX=m
CONFIG_DVB_BUDGET_CORE=m
CONFIG_DVB_PLUTO2=m
CONFIG_SMS_SIANO_MDTV=m
CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
CONFIG_SMS_USB_DRV=m
CONFIG_SMS_SDIO_DRV=m
CONFIG_DVB_TTUSB_DEC=m
@ -2636,6 +2689,7 @@ CONFIG_DVB_FIREDTV=m
CONFIG_DVB_NGENE=m
CONFIG_DVB_DDBRIDGE=m
CONFIG_DVB_USB_TECHNISAT_USB2=m
CONFIG_DVB_USB_V2=m
CONFIG_DVB_AV7110=m
CONFIG_DVB_AV7110_OSD=y
@ -2648,7 +2702,10 @@ CONFIG_DVB_TTUSB_BUDGET=m
CONFIG_DVB_USB_CINERGY_T2=m
CONFIG_DVB_B2C2_FLEXCOP=m
# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set
CONFIG_DVB_B2C2_FLEXCOP_PCI=m
# CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG is not set
CONFIG_DVB_B2C2_FLEXCOP_USB=m
# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
CONFIG_DVB_USB=m
@ -2720,9 +2777,13 @@ CONFIG_IR_ENE=m
CONFIG_IR_STREAMZAP=m
CONFIG_IR_WINBOND_CIR=m
CONFIG_IR_IGUANA=m
CONFIG_IR_TTUSBIR=m
CONFIG_IR_GPIO_CIR=m
CONFIG_V4L_MEM2MEM_DRIVERS=y
# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
# CONFIG_V4L_TEST_DRIVERS is not set
# CONFIG_VIDEO_MEM2MEM_TESTDEV is not set
#
@ -2789,7 +2850,7 @@ CONFIG_FB_I810_I2C=y
# CONFIG_FB_SM501 is not set
# CONFIG_FB_SMSCUFX is not set
CONFIG_FB_TILEBLITTING=y
# CONFIG_FB_MODE_HELPERS is not set
CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_UVESA is not set
CONFIG_FB_VESA=y
@ -3096,6 +3157,7 @@ CONFIG_HID_MULTITOUCH=m
CONFIG_HID_NTRIG=y
CONFIG_HID_QUANTA=y
CONFIG_HID_PRIMAX=m
CONFIG_HID_PS3REMOTE=m
CONFIG_HID_PRODIKEYS=m
CONFIG_HID_DRAGONRISE=m
CONFIG_HID_GYRATION=m
@ -3115,6 +3177,7 @@ CONFIG_HID_TOPSEED=m
CONFIG_HID_THRUSTMASTER=m
CONFIG_HID_ZEROPLUS=m
CONFIG_HID_ZYDACRON=m
# CONFIG_HID_SENSOR_HUB is not set
CONFIG_HID_EMS_FF=m
CONFIG_HID_ELECOM=m
CONFIG_HID_UCLOGIC=m
@ -3306,6 +3369,7 @@ CONFIG_USB_SERIAL_MCT_U232=m
CONFIG_USB_SERIAL_MOS7720=m
CONFIG_USB_SERIAL_MOS7715_PARPORT=y
# CONFIG_USB_SERIAL_ZIO is not set
# CONFIG_USB_SERIAL_ZTE is not set
CONFIG_USB_SERIAL_MOS7840=m
CONFIG_USB_SERIAL_MOTOROLA=m
CONFIG_USB_SERIAL_NAVMAN=m
@ -3346,6 +3410,7 @@ CONFIG_USB_ADUTUX=m
CONFIG_USB_SEVSEG=m
CONFIG_USB_ALI_M5632=y
CONFIG_USB_APPLEDISPLAY=m
# CONFIG_OMAP_USB2 is not set
CONFIG_USB_ATM=m
CONFIG_USB_CXACRU=m
# CONFIG_USB_C67X00_HCD is not set
@ -3364,6 +3429,7 @@ CONFIG_USB_FILE_STORAGE=m
CONFIG_USB_IOWARRIOR=m
CONFIG_USB_ISIGHTFW=m
CONFIG_USB_YUREX=m
CONFIG_USB_EZUSB_FX2=m
CONFIG_USB_LCD=m
CONFIG_USB_LD=m
CONFIG_USB_LEGOTOWER=m
@ -3614,6 +3680,7 @@ CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CIFS=m
CONFIG_CIFS_STATS=y
# CONFIG_CIFS_STATS2 is not set
CONFIG_CIFS_SMB2=y
CONFIG_CIFS_UPCALL=y
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
@ -3785,6 +3852,7 @@ CONFIG_DEBUG_NX_TEST=m
CONFIG_DEBUG_SET_MODULE_RONX=y
CONFIG_DEBUG_BOOT_PARAMS=y
CONFIG_DEBUG_VM=y
# CONFIG_DEBUG_VM_RB is not set # revisit this if performance isn't horrible
# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
CONFIG_LOCKUP_DETECTOR=y
# CONFIG_DEBUG_INFO_REDUCED is not set
@ -3948,6 +4016,8 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=m
CONFIG_BACKLIGHT_PROGEAR=m
# CONFIG_BACKLIGHT_ADP8860 is not set
# CONFIG_BACKLIGHT_ADP8870 is not set
# CONFIG_BACKLIGHT_LM3630 is not set
# CONFIG_BACKLIGHT_LM3639 is not set
CONFIG_FB_NVIDIA_BACKLIGHT=y
CONFIG_FB_RIVA_BACKLIGHT=y
CONFIG_FB_RADEON_BACKLIGHT=y
@ -3999,10 +4069,15 @@ CONFIG_KEXEC=y
CONFIG_HWMON=y
# CONFIG_HWMON_DEBUG_CHIP is not set
CONFIG_THERMAL_HWMON=y
# CONFIG_CPU_THERMAL is not set
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
#
# Bus devices
#
# CONFIG_OMAP_OCP2SCP is not set
CONFIG_CONNECTOR=y
CONFIG_PROC_EVENTS=y
@ -4037,6 +4112,8 @@ CONFIG_NET_VENDOR_SMC=y
# CONFIG_MOUSE_ATIXL is not set
# CONFIG_MEDIA_PARPORT_SUPPORT is not set
CONFIG_RADIO_ADAPTERS=y
CONFIG_RADIO_TEA5764=m
CONFIG_RADIO_SAA7706H=m
@ -4083,6 +4160,7 @@ CONFIG_LEDS_CLASS=y
# CONFIG_LEDS_PCA9633 is not set
CONFIG_LEDS_DELL_NETBOOKS=m
# CONFIG_LEDS_TCA6507 is not set
# CONFIG_LEDS_LM355x is not set
# CONFIG_LEDS_OT200 is not set
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=m
@ -4090,12 +4168,14 @@ CONFIG_LEDS_TRIGGER_ONESHOT=m
CONFIG_LEDS_TRIGGER_IDE_DISK=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=m
CONFIG_LEDS_TRIGGER_BACKLIGHT=m
# CONFIG_LEDS_TRIGGER_CPU is not set
CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
CONFIG_LEDS_TRIGGER_TRANSIENT=m
CONFIG_LEDS_ALIX2=m
CONFIG_LEDS_CLEVO_MAIL=m
CONFIG_LEDS_INTEL_SS4200=m
CONFIG_LEDS_LM3530=m
# CONFIG_LEDS_LM3642 is not set
CONFIG_LEDS_LM3556=m
CONFIG_LEDS_BLINKM=m
CONFIG_LEDS_LP3944=m
@ -4129,6 +4209,8 @@ CONFIG_FTRACE_MCOUNT_RECORD=y
# CONFIG_TRACE_BRANCH_PROFILING is not set
CONFIG_FUNCTION_PROFILER=y
CONFIG_RING_BUFFER_BENCHMARK=m
# CONFIG_RBTREE_TEST is not set
# CONFIG_INTERVAL_TREE_TEST is not set
CONFIG_FUNCTION_TRACER=y
CONFIG_STACK_TRACER=y
# CONFIG_FUNCTION_GRAPH_TRACER is not set
@ -4344,9 +4426,19 @@ CONFIG_ALTERA_STAPL=m
# CONFIG_WIMAX_GDM72XX is not set
# CONFIG_IPACK_BUS is not set
# CONFIG_CSR_WIFI is not set
#
# CONFIG_ZCACHE2 is not set
# CONFIG_NET_VENDOR_SILICOM is not set
# CONFIG_SBYPASS is not set
# CONFIG_BPCTL is not set
# CONFIG_CED1401 is not set
# CONFIG_DGRP is not set
# END OF STAGING
#
# Remoteproc drivers (EXPERIMENTAL)
#
# CONFIG_STE_MODEM_RPROC is not set
CONFIG_LIBFC=m
CONFIG_LIBFCOE=m
CONFIG_FCOE=m
@ -4490,3 +4582,4 @@ CONFIG_IOMMU_SUPPORT=y
# CONFIG_CRYPTO_KEY_TYPE is not set
# CONFIG_PGP_LIBRARY is not set
# CONFIG_PGP_PRELOAD is not set
# CONFIG_ASYMMETRIC_KEY_TYPE is not set

View File

@ -372,3 +372,11 @@ CONFIG_RCU_FANOUT_LEAF=16
# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
# CONFIG_FAIL_IOMMU is not set
# CONFIG_PPC_DENORMALISATION is not set
# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
# CONFIG_GPIO_ADNP is not set
# CONFIG_MFD_SYSCON is not set
# CONFIG_RTC_DRV_SNVS is not set
# CONFIG_ASYMMETRIC_KEY_TYPE is not set

View File

@ -167,7 +167,10 @@ CONFIG_HW_RANDOM_AMD=m
CONFIG_UIO_PDRV=m
CONFIG_HW_RANDOM_PSERIES=m
CONFIG_CRYPTO_DEV_NX=m
CONFIG_CRYPTO_DEV_NX=y
CONFIG_CRYPTO_842=m
CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
CONFIG_CRYPTO_DEV_NX_COMPRESS=m
CONFIG_BPF_JIT=y

View File

@ -241,3 +241,12 @@ CONFIG_STRICT_DEVMEM=y
CONFIG_CRYPTO_GHASH_S390=m
CONFIG_NET_CORE=y
CONFIG_ETHERNET=y
CONFIG_BPF_JIT=y
# CONFIG_TRANSPARENT_HUGEPAGE is not set
# CONFIG_SCM_BUS is not set
# CONFIG_EADM_SCH is not set
# CONFIG_SCM_BLOCK is not set
# CONFIG_SCM_BLOCK_CLUSTER_WRITE is not set
# CONFIG_S390_PTDUMP is not set
# CONFIG_ASYMMETRIC_KEY_TYPE is not set

View File

@ -201,3 +201,17 @@ CONFIG_CRYPTO_DEV_NIAGARA2=y
CONFIG_BPF_JIT=y
# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
# CONFIG_IRQ_DOMAIN_DEBUG is not set
# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
# CONFIG_MFD_SYSCON is not set
# CONFIG_RTC_DRV_SNVS is not set
# CONFIG_CRYPTO_CRC32C_SPARC64 is not set
# CONFIG_CRYPTO_MD5_SPARC64 is not set
# CONFIG_CRYPTO_SHA1_SPARC64 is not set
# CONFIG_CRYPTO_SHA256_SPARC64 is not set
# CONFIG_CRYPTO_SHA512_SPARC64 is not set
# CONFIG_CRYPTO_AES_SPARC64 is not set
# CONFIG_CRYPTO_CAMELLIA_SPARC64 is not set
# CONFIG_CRYPTO_DES_SPARC64 is not set
# CONFIG_ASYMMETRIC_KEY_TYPE is not set

View File

@ -190,6 +190,7 @@ CONFIG_SERIAL_GRLIB_GAISLER_APBUART=m
# CONFIG_X86_INTEL_MID is not set
CONFIG_MFD_CS5535=m
# CONFIG_MFD_SYSCON is not set
# I2O enabled only for 32-bit x86, disabled for PAE kernel
CONFIG_I2O=m
@ -211,5 +212,8 @@ CONFIG_I2O_BUS=m
# CONFIG_GEOS is not set
# CONFIG_NET5501 is not set
# CONFIG_MDIO_BUS_MUX_GPIO is not set
# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
# CONFIG_GPIO_SODAVILLE is not set
# CONFIG_GPIO_ADNP is not set
# CONFIG_BACKLIGHT_OT200 is not set
# CONFIG_RTC_DRV_SNVS is not set

View File

@ -91,10 +91,11 @@ CONFIG_ACPI_APEI_MEMORY_FAILURE=y
# CONFIG_ACPI_APEI_EINJ is not set
CONFIG_ACPI_IPMI=m
CONFIG_ACPI_CUSTOM_METHOD=m
CONFIG_ACPI_BGRT=m
CONFIG_ACPI_BGRT=y
CONFIG_X86_ACPI_CPUFREQ=y
CONFIG_X86_PCC_CPUFREQ=y
CONFIG_X86_ACPI_CPUFREQ_CPB=y
CONFIG_X86_POWERNOW_K8=y
CONFIG_X86_P4_CLOCKMOD=y
# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
@ -424,3 +425,5 @@ CONFIG_INTEL_MEI=m
# Maybe enable in debug kernels?
# CONFIG_DEBUG_NMI_SELFTEST is not set

View File

@ -46,6 +46,8 @@ CONFIG_CRYPTO_SHA1_SSSE3=m
CONFIG_CRYPTO_BLOWFISH_X86_64=m
CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=m
CONFIG_CRYPTO_CAMELLIA_X86_64=m
CONFIG_CRYPTO_CAST5_AVX_X86_64=m
CONFIG_CRYPTO_CAST6_AVX_X86_64=m
CONFIG_CRYPTO_SERPENT_AVX_X86_64=m
CONFIG_CRYPTO_TWOFISH_AVX_X86_64=m
@ -107,6 +109,7 @@ CONFIG_X86_X2APIC=y
CONFIG_SPARSE_IRQ=y
CONFIG_RCU_FANOUT=64
# CONFIG_RCU_USER_QS is not set
CONFIG_INTEL_TXT=y

View File

@ -1,27 +0,0 @@
From 696199f8ccf7fc6d17ef89c296ad3b6c78c52d9c Mon Sep 17 00:00:00 2001
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Thu, 29 Nov 2012 22:00:51 -0500
Subject: [PATCH] don't do blind d_drop() in nfs_prime_dcache()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/nfs/dir.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index ce8cb92..99489cf 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -450,7 +450,8 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
nfs_refresh_inode(dentry->d_inode, entry->fattr);
goto out;
} else {
- d_drop(dentry);
+ if (d_invalidate(dentry) != 0)
+ goto out;
dput(dentry);
}
}
--
1.8.0.1

View File

@ -1,26 +0,0 @@
commit 93f9052643409c13b3b5f76833865087351f55b8
Author: Theodore Ts'o <tytso@mit.edu>
Date: Wed Sep 12 14:32:42 2012 -0400
ext4: set bg_itable_unused when resizing
Set bg_itable_unused for file systems that have uninit_bg enabled.
This will speed up the first e2fsck run after the file system is
resized.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 7adc088..a5be589 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1268,6 +1268,9 @@ static int ext4_setup_new_descs(handle_t *handle, struct super_block *sb,
ext4_free_group_clusters_set(sb, gdp,
EXT4_B2C(sbi, group_data->free_blocks_count));
ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb));
+ if (ext4_has_group_desc_csum(sb))
+ ext4_itable_unused_set(sb, gdp,
+ EXT4_INODES_PER_GROUP(sb));
gdp->bg_flags = cpu_to_le16(*bg_flags);
ext4_group_desc_csum_set(sb, group, gdp);

View File

@ -1,74 +0,0 @@
Lock splice_read and splice_write functions
commit 1a25b1c4ce189e3926f2981f3302352a930086db
Author: Mikulas Patocka <mpatocka@redhat.com>
Date: Mon Oct 15 17:20:17 2012 -0400
Lock splice_read and splice_write functions
Functions generic_file_splice_read and generic_file_splice_write access
the pagecache directly. For block devices these functions must be locked
so that block size is not changed while they are in progress.
This patch is an additional fix for commit b87570f5d349 ("Fix a crash
when block device is read and block size is changed at the same time")
that locked aio_read, aio_write and mmap against block size change.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Index: linux-3.6.x86_64/fs/block_dev.c
===================================================================
--- linux-3.6.x86_64.orig/fs/block_dev.c 2012-11-16 17:12:57.352936580 -0500
+++ linux-3.6.x86_64/fs/block_dev.c 2012-11-16 17:13:11.908887989 -0500
@@ -1662,6 +1662,39 @@
return ret;
}
+static ssize_t blkdev_splice_read(struct file *file, loff_t *ppos,
+ struct pipe_inode_info *pipe, size_t len,
+ unsigned int flags)
+{
+ ssize_t ret;
+ struct block_device *bdev = I_BDEV(file->f_mapping->host);
+
+ percpu_down_read(&bdev->bd_block_size_semaphore);
+
+ ret = generic_file_splice_read(file, ppos, pipe, len, flags);
+
+ percpu_up_read(&bdev->bd_block_size_semaphore);
+
+ return ret;
+}
+
+static ssize_t blkdev_splice_write(struct pipe_inode_info *pipe,
+ struct file *file, loff_t *ppos, size_t len,
+ unsigned int flags)
+{
+ ssize_t ret;
+ struct block_device *bdev = I_BDEV(file->f_mapping->host);
+
+ percpu_down_read(&bdev->bd_block_size_semaphore);
+
+ ret = generic_file_splice_write(pipe, file, ppos, len, flags);
+
+ percpu_up_read(&bdev->bd_block_size_semaphore);
+
+ return ret;
+}
+
+
/*
* Try to release a page associated with block device when the system
* is under memory pressure.
@@ -1700,8 +1733,8 @@
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_blkdev_ioctl,
#endif
- .splice_read = generic_file_splice_read,
- .splice_write = generic_file_splice_write,
+ .splice_read = blkdev_splice_read,
+ .splice_write = blkdev_splice_write,
};
int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg)

View File

@ -54,19 +54,19 @@ Summary: The Linux kernel
# For non-released -rc kernels, this will be appended after the rcX and
# gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
#
%global baserelease 8
%global baserelease 101
%global fedora_build %{baserelease}
# base_sublevel is the kernel version we're starting with and patching
# on top of -- for example, 2.6.22-rc7-git1 starts with a 2.6.21 base,
# which yields a base_sublevel of 21.
%define base_sublevel 6
%define base_sublevel 7
## If this is a released kernel ##
%if 0%{?released_kernel}
# Do we have a -stable update to apply?
%define stable_update 11
%define stable_update 3
# Is it a -stable RC?
%define stable_rc 0
# Set rpm version accordingly
@ -712,7 +712,6 @@ Patch19000: ips-noirq.patch
# ARM
Patch21000: arm-read_current_timer.patch
Patch21001: arm-fix-omapdrm.patch
Patch21002: arm-fix_radio_shark.patch
Patch21003: arm-alignment-faults.patch
# OMAP
@ -722,7 +721,6 @@ Patch21005: arm-tegra-usb-no-reset-linux33.patch
Patch21006: arm-tegra-sdhci-module-fix.patch
# ARM highbank patches
Patch21010: arm-highbank-sata-fix.patch
#rhbz 754518
Patch21235: scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch
@ -739,69 +737,20 @@ Patch22014: efifb-skip-DMI-checks-if-bootloader-knows.patch
#rhbz 857324
Patch22070: net-tcp-bz857324.patch
#rhbz 869904 869909 CVE-2012-4508
Patch22080: 0001-ext4-ext4_inode_info-diet.patch
Patch22081: 0002-ext4-give-i_aiodio_unwritten-a-more-appropriate-name.patch
Patch22082: 0003-ext4-fix-unwritten-counter-leakage.patch
Patch22083: 0004-ext4-completed_io-locking-cleanup.patch
Patch22084: 0005-ext4-serialize-dio-nonlocked-reads-with-defrag-worke.patch
Patch22085: 0006-ext4-serialize-unlocked-dio-reads-with-truncate.patch
Patch22086: 0007-ext4-endless-truncate-due-to-nonlocked-dio-readers.patch
Patch22087: 0008-ext4-serialize-truncate-with-owerwrite-DIO-workers.patch
Patch22088: 0009-ext4-punch_hole-should-wait-for-DIO-writers.patch
Patch22089: 0010-ext4-fix-ext_remove_space-for-punch_hole-case.patch
Patch22090: 0011-ext4-fix-ext4_flush_completed_IO-wait-semantics.patch
Patch22091: 0012-ext4-serialize-fallocate-with-ext4_convert_unwritten.patch
Patch22100: uprobes-upstream-backport.patch
#rhbz 871078
Patch22112: USB-report-submission-of-active-URBs.patch
#rhbz 869341
Patch22113: smp_irq_move_cleanup_interrupt.patch
#rhbz 812129
Patch22120: block-fix-a-crash-when-block-device-is.patch
Patch22121: blockdev-turn-a-rw-semaphore-into-a-percpu-rw-sem.patch
Patch22122: fs-lock-splice_read-and-splice_write-functions.patch
#rhbz 874791
Patch22125: Bluetooth-Add-support-for-BCM20702A0.patch
#rhbz CVE-2012-4530 868285 880147
Patch21228: exec-do-not-leave-bprm-interp-on-stack.patch
Patch21229: exec-use-eloop-for-max-recursion-depth.patch
#rhbz 869629
Patch21230: SCSI-mvsas-Fix-oops-when-ata-commond-timeout.patch
#rhbz 851278
Patch21231: 8139cp-revert-set-ring-address-before-enabling-receiver.patch
Patch21232: 8139cp-set-ring-address-after-enabling-C-mode.patch
Patch21233: 8139cp-re-enable-interrupts-after-tx-timeout.patch
#rhbz 883414
Patch21234: mac80211-fix-ibss-scanning.patch
#rhbz 873107
Patch21237: 0001-ACPI-sony-laptop-do-proper-memcpy-for-ACPI_TYPE_INTE.patch
#rhbz 874372
Patch21238: don-t-do-blind-d_drop-in-nfs_prime_dcache.patch
#rhbz 853064
Patch21239: aoe-remove-extra-bdi_init.patch
#rhbz 890547
Patch21240: ACPI-do-not-use-Lid-and-Sleep-button-for-S5-wakeup.patch
#rhbz 886946
Patch21241: iwlegacy-fix-IBSS-cleanup.patch
#rhbz 852833
Patch21245: ext4-set-bg_itable_unused-when-resizing.patch
#rhbz 896051 896038 CVE-2013-0190
Patch21250: xen-fix-stack-corruption-in-xen_failsafe_callback.patch
@ -1369,13 +1318,11 @@ ApplyPatch vmbugon-warnon.patch
#
# ARM
#
ApplyPatch arm-read_current_timer.patch
ApplyPatch arm-fix-omapdrm.patch
ApplyPatch arm-fix_radio_shark.patch
#ApplyPatch arm-read_current_timer.patch
#ApplyPatch arm-fix-omapdrm.patch
ApplyPatch arm-tegra-nvec-kconfig.patch
ApplyPatch arm-tegra-usb-no-reset-linux33.patch
ApplyPatch arm-tegra-sdhci-module-fix.patch
ApplyPatch arm-highbank-sata-fix.patch
ApplyPatch arm-alignment-faults.patch
#
@ -1450,7 +1397,7 @@ ApplyPatch linux-2.6-e1000-ich9-montevina.patch
# DRM core
#ApplyPatch drm-edid-try-harder-to-fix-up-broken-headers.patch
ApplyPatch drm-vgem.patch
#ApplyPatch drm-vgem.patch
# Nouveau DRM
@ -1493,74 +1440,25 @@ ApplyPatch weird-root-dentry-name-debug.patch
#selinux ptrace child permissions
ApplyPatch selinux-apply-different-permission-to-ptrace-child.patch
ApplyPatch efifb-skip-DMI-checks-if-bootloader-knows.patch
# ApplyPatch efifb-skip-DMI-checks-if-bootloader-knows.patch
#rhbz 857324
ApplyPatch net-tcp-bz857324.patch
#rhbz 869904 869909 CVE-2012-4508
ApplyPatch 0001-ext4-ext4_inode_info-diet.patch
ApplyPatch 0002-ext4-give-i_aiodio_unwritten-a-more-appropriate-name.patch
ApplyPatch 0003-ext4-fix-unwritten-counter-leakage.patch
ApplyPatch 0004-ext4-completed_io-locking-cleanup.patch
ApplyPatch 0005-ext4-serialize-dio-nonlocked-reads-with-defrag-worke.patch
ApplyPatch 0006-ext4-serialize-unlocked-dio-reads-with-truncate.patch
ApplyPatch 0007-ext4-endless-truncate-due-to-nonlocked-dio-readers.patch
ApplyPatch 0008-ext4-serialize-truncate-with-owerwrite-DIO-workers.patch
ApplyPatch 0009-ext4-punch_hole-should-wait-for-DIO-writers.patch
ApplyPatch 0010-ext4-fix-ext_remove_space-for-punch_hole-case.patch
ApplyPatch 0011-ext4-fix-ext4_flush_completed_IO-wait-semantics.patch
ApplyPatch 0012-ext4-serialize-fallocate-with-ext4_convert_unwritten.patch
ApplyPatch uprobes-upstream-backport.patch
#rhbz 871078
ApplyPatch USB-report-submission-of-active-URBs.patch
#rhbz 869341
ApplyPatch smp_irq_move_cleanup_interrupt.patch
#rhbz 812129
ApplyPatch block-fix-a-crash-when-block-device-is.patch
ApplyPatch blockdev-turn-a-rw-semaphore-into-a-percpu-rw-sem.patch
ApplyPatch fs-lock-splice_read-and-splice_write-functions.patch
#rhbz 874791
ApplyPatch Bluetooth-Add-support-for-BCM20702A0.patch
#rhbz CVE-2012-4530 868285 880147
ApplyPatch exec-do-not-leave-bprm-interp-on-stack.patch
ApplyPatch exec-use-eloop-for-max-recursion-depth.patch
#rhbz 869629
ApplyPatch SCSI-mvsas-Fix-oops-when-ata-commond-timeout.patch
#rhbz 851278
ApplyPatch 8139cp-revert-set-ring-address-before-enabling-receiver.patch -R
ApplyPatch 8139cp-set-ring-address-after-enabling-C-mode.patch
ApplyPatch 8139cp-re-enable-interrupts-after-tx-timeout.patch
#rhbz 883414
ApplyPatch mac80211-fix-ibss-scanning.patch
#rhbz 873107
ApplyPatch 0001-ACPI-sony-laptop-do-proper-memcpy-for-ACPI_TYPE_INTE.patch
#rhbz 874372
ApplyPatch don-t-do-blind-d_drop-in-nfs_prime_dcache.patch
#rhbz 853064
ApplyPatch aoe-remove-extra-bdi_init.patch
#rhbz 890547
ApplyPatch ACPI-do-not-use-Lid-and-Sleep-button-for-S5-wakeup.patch
#rhbz 886946
ApplyPatch iwlegacy-fix-IBSS-cleanup.patch
#rhbz 852833
ApplyPatch ext4-set-bg_itable_unused-when-resizing.patch
#rhbz 896051 896038 CVE-2013-0190
ApplyPatch xen-fix-stack-corruption-in-xen_failsafe_callback.patch
@ -1788,8 +1686,8 @@ BuildKernel() {
# Make sure the Makefile and version.h have a matching timestamp so that
# external modules can be built
touch -r $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/Makefile $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/include/linux/version.h
touch -r $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/.config $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/include/linux/autoconf.h
touch -r $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/Makefile $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/include/generated/uapi/linux/version.h
# Copy .config to include/config/auto.conf so "make prepare" is unnecessary.
cp $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/.config $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/include/config/auto.conf
@ -2298,6 +2196,7 @@ fi
%dir %{_libexecdir}/perf-core
%{_libexecdir}/perf-core/*
%{_mandir}/man[1-8]/perf*
%{_sysconfdir}/bash_completion.d/perf
%doc linux-%{KVERREL}/tools/perf/Documentation/examples.txt
%files -n python-perf
@ -2427,6 +2326,9 @@ fi
# '-' | |
# '-'
%changelog
* Fri Jan 18 2013 Josh Boyer <jwboyer@redhat.com> - 3.7.3-101
- Linux v3.7.3
* Wed Jan 16 2013 Justin M. Forbes <jforbes@redhat.com> - 3.6.11-8
- Fix for CVE-2013-0190 xen corruption with 32bit pvops (rhbz 896051 896038)
- Fix resize2fs issue with ext4 (rhbz 852833)

View File

@ -28,14 +28,14 @@ index 2209620..659c1bb 100644
quot = uart_get_divisor(port, baud);
@@ -2240,7 +2251,7 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
struct uart_8250_port *up = (struct uart_8250_port *)port;
container_of(port, struct uart_8250_port, port);
unsigned char cval, fcr = 0;
unsigned long flags;
- unsigned int baud, quot;
+ unsigned int baud, quot, max_baud;
int fifo_bug = 0;
switch (termios->c_cflag & CSIZE) {
case CS5:
@@ -2272,9 +2283,10 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
/*
* Ask the core to calculate the divisor for us.

View File

@ -28,9 +28,9 @@ index 35c67e0..42dce2a 100644
-static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000};
+/* LIS3DC: 0 = power off, above 9 = undefined */
+static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000, -1, -1, -1, -1, -1, -1};
static int lis3_3dlh_rates[4] = {50, 100, 400, 1000};
/* ODR is Output Data Rate */
static int lis3lv02d_get_odr(struct lis3lv02d *lis3)
@@ -202,12 +203,11 @@ static int lis3lv02d_get_odr(struct lis3lv02d *lis3)
return lis3->odrs[(ctrl >> shift)];
}

View File

@ -1,132 +0,0 @@
Do not scan on no-IBSS and disabled channels in IBSS mode. Doing this
can trigger Microcode errors on iwlwifi and iwlegacy drivers.
Also rename ieee80211_request_internal_scan() function since it is only
used in IBSS mode and simplify calling it from ieee80211_sta_find_ibss().
This patch should address:
https://bugzilla.redhat.com/show_bug.cgi?id=883414
https://bugzilla.kernel.org/show_bug.cgi?id=49411
Reported-by: Jesse Kahtava <jesse_kahtava@f-m.fm>
Reported-by: Mikko Rapeli <mikko.rapeli@iki.fi>
Cc: stable@vger.kernel.org
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
net/mac80211/ibss.c | 9 ++++-----
net/mac80211/ieee80211_i.h | 6 +++---
net/mac80211/scan.c | 34 ++++++++++++++++++++++++----------
3 files changed, 31 insertions(+), 18 deletions(-)
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index c21e33d..d9df6b8 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -678,8 +678,8 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
sdata_info(sdata,
"No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n");
- ieee80211_request_internal_scan(sdata,
- ifibss->ssid, ifibss->ssid_len, NULL);
+ ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len,
+ NULL);
}
static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
@@ -777,9 +777,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
IEEE80211_SCAN_INTERVAL)) {
sdata_info(sdata, "Trigger new scan to find an IBSS to join\n");
- ieee80211_request_internal_scan(sdata,
- ifibss->ssid, ifibss->ssid_len,
- ifibss->fixed_channel ? ifibss->channel : NULL);
+ ieee80211_request_ibss_scan(sdata, ifibss->ssid,
+ ifibss->ssid_len, chan);
} else {
int interval = IEEE80211_SCAN_INTERVAL;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 156e583..bc48d4d 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1247,9 +1247,9 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
/* scan/BSS handling */
void ieee80211_scan_work(struct work_struct *work);
-int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
- const u8 *ssid, u8 ssid_len,
- struct ieee80211_channel *chan);
+int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
+ const u8 *ssid, u8 ssid_len,
+ struct ieee80211_channel *chan);
int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
struct cfg80211_scan_request *req);
void ieee80211_scan_cancel(struct ieee80211_local *local);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 43e60b5..fab706f 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -819,9 +819,9 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
return res;
}
-int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
- const u8 *ssid, u8 ssid_len,
- struct ieee80211_channel *chan)
+int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
+ const u8 *ssid, u8 ssid_len,
+ struct ieee80211_channel *chan)
{
struct ieee80211_local *local = sdata->local;
int ret = -EBUSY;
@@ -835,22 +835,36 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
/* fill internal scan request */
if (!chan) {
- int i, nchan = 0;
+ int i, max_n;
+ int n_ch = 0;
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
if (!local->hw.wiphy->bands[band])
continue;
- for (i = 0;
- i < local->hw.wiphy->bands[band]->n_channels;
- i++) {
- local->int_scan_req->channels[nchan] =
+
+ max_n = local->hw.wiphy->bands[band]->n_channels;
+ for (i = 0; i < max_n; i++) {
+ struct ieee80211_channel *tmp_ch =
&local->hw.wiphy->bands[band]->channels[i];
- nchan++;
+
+ if (tmp_ch->flags & (IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_DISABLED))
+ continue;
+
+ local->int_scan_req->channels[n_ch] = tmp_ch;
+ n_ch++;
}
}
- local->int_scan_req->n_channels = nchan;
+ if (WARN_ON_ONCE(n_ch == 0))
+ goto unlock;
+
+ local->int_scan_req->n_channels = n_ch;
} else {
+ if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_DISABLED)))
+ goto unlock;
+
local->int_scan_req->channels[0] = chan;
local->int_scan_req->n_channels = 1;
}
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

View File

@ -1,50 +0,0 @@
commit 94777fc51b3ad85ff9f705ddf7cdd0eb3bbad5a6
Author: Dimitri Sivanich <sivanich@sgi.com>
Date: Tue Oct 16 07:50:21 2012 -0500
x86/irq/ioapic: Check for valid irq_cfg pointer in smp_irq_move_cleanup_interrupt
Posting this patch to fix an issue concerning sparse irq's that
I raised a while back. There was discussion about adding
refcounting to sparse irqs (to fix other potential race
conditions), but that does not appear to have been addressed
yet. This covers the only issue of this type that I've
encountered in this area.
A NULL pointer dereference can occur in
smp_irq_move_cleanup_interrupt() if we haven't yet setup the
irq_cfg pointer in the irq_desc.irq_data.chip_data.
In create_irq_nr() there is a window where we have set
vector_irq in __assign_irq_vector(), but not yet called
irq_set_chip_data() to set the irq_cfg pointer.
Should an IRQ_MOVE_CLEANUP_VECTOR hit the cpu in question during
this time, smp_irq_move_cleanup_interrupt() will attempt to
process the aforementioned irq, but panic when accessing
irq_cfg.
Only continue processing the irq if irq_cfg is non-NULL.
Signed-off-by: Dimitri Sivanich <sivanich@sgi.com>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Joerg Roedel <joerg.roedel@amd.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Alexander Gordeev <agordeev@redhat.com>
Link: http://lkml.kernel.org/r/20121016125021.GA22935@sgi.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index c265593..1817fa9 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2257,6 +2257,9 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
continue;
cfg = irq_cfg(irq);
+ if (!cfg)
+ continue;
+
raw_spin_lock(&desc->lock);
/*

View File

@ -1,2 +1,2 @@
1a1760420eac802c541a20ab51a093d1 linux-3.6.tar.xz
bd4bba74093405887d521309a74c19e9 patch-3.6.11.xz
21223369d682bcf44bcdfe1521095983 linux-3.7.tar.xz
d4aa39ec9610e9fbd7bb4f5aff2c5db8 patch-3.7.3.xz

File diff suppressed because it is too large Load Diff