Rebase to 3.7.1
This commit is contained in:
parent
8b89f2ce46
commit
03fb1ee574
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -1,67 +1,3 @@
|
|||
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
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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"
|
|
@ -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");
|
|
@ -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,
|
|
@ -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
|
|
@ -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
|
||||
|
@ -35,13 +37,14 @@ CONFIG_ARM_ERRATA_742230=y
|
|||
CONFIG_ARM_ERRATA_742231=y
|
||||
CONFIG_ARM_ERRATA_754327=y
|
||||
CONFIG_ARM_ERRATA_764369=y
|
||||
|
||||
CONFIG_ARM_ERRATA_775420=y
|
||||
|
||||
# Generic ARM config options
|
||||
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,24 +94,20 @@ 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
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_PINCTRL_SINGLE=m
|
||||
|
||||
CONFIG_USB_ULPI=y
|
||||
|
@ -136,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
|
||||
|
||||
|
@ -234,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
|
||||
|
@ -252,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
|
||||
|
||||
|
@ -263,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
|
||||
|
@ -272,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
|
||||
|
@ -292,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
|
||||
|
@ -356,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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -176,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
|
||||
|
@ -185,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=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
|
||||
|
@ -228,6 +233,7 @@ CONFIG_OMAP2_DSS_SLEEP_BEFORE_RESET=y
|
|||
CONFIG_OMAP2_DSS_SLEEP_AFTER_VENC_RESET=y
|
||||
|
||||
CONFIG_PANEL_TFP410=m
|
||||
CONFIG_PANEL_TAAL=m
|
||||
CONFIG_PANEL_PICODLP=m
|
||||
CONFIG_BACKLIGHT_PANDORA=m
|
||||
|
||||
|
@ -240,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
|
||||
|
@ -292,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
|
||||
|
|
|
@ -18,7 +18,6 @@ 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
|
||||
|
|
120
config-generic
120
config-generic
|
@ -190,30 +190,76 @@ CONFIG_EXTRA_FIRMWARE=""
|
|||
# Memory Technology Devices (MTD)
|
||||
#
|
||||
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 is not set
|
||||
# CONFIG_MTD_BLOCK is not set
|
||||
# CONFIG_MTD_BLOCK_RO 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 is not set
|
||||
# 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_MTD_UBI=m
|
||||
|
||||
CONFIG_MTD_UBI_WL_THRESHOLD=4096
|
||||
CONFIG_MTD_UBI_BEB_LIMIT=20
|
||||
# CONFIG_MTD_UBI_FASTMAP is not set
|
||||
# CONFIG_MTD_UBI_GLUEBI is not set
|
||||
|
||||
#
|
||||
# Parallel port support
|
||||
|
@ -433,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
|
||||
|
@ -603,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
|
||||
|
@ -682,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
|
||||
|
@ -825,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
|
||||
|
@ -833,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
|
||||
|
@ -864,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
|
||||
|
@ -1053,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
|
||||
|
@ -1305,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
|
||||
|
@ -1360,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
|
||||
|
||||
|
@ -1474,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 is not set
|
||||
# CONFIG_HOSTAP is not set
|
||||
|
@ -2020,6 +2077,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
|
||||
|
@ -2046,6 +2104,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
|
||||
|
@ -2054,6 +2113,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
|
||||
|
@ -2142,6 +2202,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
|
||||
|
@ -2261,6 +2322,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
|
||||
|
@ -2275,6 +2337,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
|
||||
|
@ -2346,6 +2409,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
|
||||
|
@ -2379,6 +2443,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
|
||||
|
@ -2436,6 +2501,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
|
||||
|
@ -2443,6 +2510,7 @@ CONFIG_DRM_I2C_CH7006=m
|
|||
CONFIG_DRM_I2C_SIL164=m
|
||||
CONFIG_DRM_UDL=m
|
||||
CONFIG_DRM_VMWGFX=m
|
||||
# CONFIG_DRM_VMWGFX_FBCON is not set
|
||||
CONFIG_DRM_VGEM=m
|
||||
|
||||
#
|
||||
|
@ -2458,6 +2526,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
|
||||
#
|
||||
|
@ -2515,6 +2585,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
|
||||
|
@ -2526,6 +2597,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
|
||||
|
@ -2589,6 +2662,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
|
||||
|
@ -2606,6 +2680,7 @@ CONFIG_DVB_FIREDTV=m
|
|||
CONFIG_DVB_NGENE=m
|
||||
CONFIG_DVB_DDBRIDGE=m
|
||||
CONFIG_DVB_USB_TECHNISAT_USB2=m
|
||||
# CONFIG_DVB_USB_V2 is not set
|
||||
|
||||
CONFIG_DVB_AV7110=m
|
||||
CONFIG_DVB_AV7110_OSD=y
|
||||
|
@ -2618,7 +2693,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
|
||||
|
@ -2690,9 +2768,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
|
||||
|
||||
#
|
||||
|
@ -3066,6 +3148,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
|
||||
|
@ -3085,6 +3168,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
|
||||
|
@ -3276,6 +3360,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
|
||||
|
@ -3316,6 +3401,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
|
||||
|
@ -3334,6 +3420,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
|
||||
|
@ -3584,6 +3671,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
|
||||
|
@ -3755,6 +3843,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
|
||||
|
@ -3768,7 +3857,6 @@ CONFIG_CROSS_MEMORY_ATTACH=y
|
|||
# CONFIG_BACKTRACE_SELF_TEST is not set
|
||||
CONFIG_LATENCYTOP=y
|
||||
CONFIG_RESOURCE_COUNTERS=y
|
||||
# CONFIG_MEMCG is not set
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
# CONFIG_DEBUG_VIRTUAL is not set
|
||||
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
|
||||
|
@ -3919,6 +4007,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
|
||||
|
@ -3970,10 +4060,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
|
||||
|
||||
|
@ -4008,6 +4103,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
|
||||
|
@ -4054,6 +4151,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
|
||||
|
@ -4061,12 +4159,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
|
||||
|
@ -4100,6 +4200,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
|
||||
|
@ -4315,9 +4417,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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -158,7 +158,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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
From 20ae2081584450e552735a3df968ce5b5946a607 Mon Sep 17 00:00:00 2001
|
||||
From 6752ab4cb863fc63ed85f1ca78a42235c09fad83 Mon Sep 17 00:00:00 2001
|
||||
From: Kees Cook <keescook@chromium.org>
|
||||
Date: Mon, 26 Nov 2012 08:56:37 -0500
|
||||
Date: Mon, 26 Nov 2012 09:07:50 -0500
|
||||
Subject: [PATCH 1/2] exec: do not leave bprm->interp on stack
|
||||
|
||||
If a series of scripts are executed, each triggering module loading via
|
||||
|
@ -73,10 +73,10 @@ index d3b8c1f..df49d48 100644
|
|||
/*
|
||||
* OK, now restart the process with the interpreter's dentry.
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index fab2c6d..59896ae 100644
|
||||
index 0039055..c6e6de4 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -1202,9 +1202,24 @@ void free_bprm(struct linux_binprm *bprm)
|
||||
@@ -1175,9 +1175,24 @@ void free_bprm(struct linux_binprm *bprm)
|
||||
mutex_unlock(¤t->signal->cred_guard_mutex);
|
||||
abort_creds(bprm->cred);
|
||||
}
|
||||
|
@ -102,10 +102,10 @@ index fab2c6d..59896ae 100644
|
|||
* install the new credentials for this executable
|
||||
*/
|
||||
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
|
||||
index 366422b..eb53e15 100644
|
||||
index cfcc6bf..de0628e 100644
|
||||
--- a/include/linux/binfmts.h
|
||||
+++ b/include/linux/binfmts.h
|
||||
@@ -128,6 +128,7 @@ extern int setup_arg_pages(struct linux_binprm * bprm,
|
||||
@@ -114,6 +114,7 @@ extern int setup_arg_pages(struct linux_binprm * bprm,
|
||||
unsigned long stack_top,
|
||||
int executable_stack);
|
||||
extern int bprm_mm_init(struct linux_binprm *bprm);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From 4ae8186cd77835b45f1b35edb4ce70309287bfc3 Mon Sep 17 00:00:00 2001
|
||||
From ba1b23d05259e31d30a78017cdfbc010dcb08aa6 Mon Sep 17 00:00:00 2001
|
||||
From: Kees Cook <keescook@chromium.org>
|
||||
Date: Mon, 26 Nov 2012 09:02:11 -0500
|
||||
Subject: [PATCH 2/2] exec: use -ELOOP for max recursion depth
|
||||
|
@ -98,10 +98,10 @@ index df49d48..8ae4be1 100644
|
|||
fput(bprm->file);
|
||||
bprm->file = NULL;
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index 59896ae..541cc51 100644
|
||||
index c6e6de4..85c1f9e 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -1398,6 +1398,10 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
|
||||
@@ -1371,6 +1371,10 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
|
||||
struct linux_binfmt *fmt;
|
||||
pid_t old_pid, old_vpid;
|
||||
|
||||
|
@ -112,7 +112,7 @@ index 59896ae..541cc51 100644
|
|||
retval = security_bprm_check(bprm);
|
||||
if (retval)
|
||||
return retval;
|
||||
@@ -1422,12 +1426,8 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
|
||||
@@ -1395,12 +1399,8 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
|
||||
if (!try_module_get(fmt->module))
|
||||
continue;
|
||||
read_unlock(&binfmt_lock);
|
||||
|
@ -127,10 +127,10 @@ index 59896ae..541cc51 100644
|
|||
if (retval >= 0) {
|
||||
if (depth == 0) {
|
||||
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
|
||||
index eb53e15..5bab59b 100644
|
||||
index de0628e..54135f6 100644
|
||||
--- a/include/linux/binfmts.h
|
||||
+++ b/include/linux/binfmts.h
|
||||
@@ -68,8 +68,6 @@ struct linux_binprm {
|
||||
@@ -54,8 +54,6 @@ struct linux_binprm {
|
||||
#define BINPRM_FLAGS_EXECFD_BIT 1
|
||||
#define BINPRM_FLAGS_EXECFD (1 << BINPRM_FLAGS_EXECFD_BIT)
|
||||
|
||||
|
@ -138,7 +138,7 @@ index eb53e15..5bab59b 100644
|
|||
-
|
||||
/* Function parameter for binfmt->coredump */
|
||||
struct coredump_params {
|
||||
long signr;
|
||||
siginfo_t *siginfo;
|
||||
--
|
||||
1.8.0
|
||||
|
||||
|
|
|
@ -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)
|
|
@ -131,62 +131,6 @@ diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.c .
|
|||
/*
|
||||
* See if we have Graphics Output Protocol
|
||||
*/
|
||||
@@ -276,8 +392,9 @@
|
||||
nr_gops = size / sizeof(void *);
|
||||
for (i = 0; i < nr_gops; i++) {
|
||||
struct efi_graphics_output_mode_info *info;
|
||||
- efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID;
|
||||
- void *pciio;
|
||||
+ efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
|
||||
+ bool conout_found = false;
|
||||
+ void *dummy;
|
||||
void *h = gop_handle[i];
|
||||
|
||||
status = efi_call_phys3(sys_table->boottime->handle_protocol,
|
||||
@@ -285,19 +402,21 @@
|
||||
if (status != EFI_SUCCESS)
|
||||
continue;
|
||||
|
||||
- efi_call_phys3(sys_table->boottime->handle_protocol,
|
||||
- h, &pciio_proto, &pciio);
|
||||
+ status = efi_call_phys3(sys_table->boottime->handle_protocol,
|
||||
+ h, &conout_proto, &dummy);
|
||||
+
|
||||
+ if (status == EFI_SUCCESS)
|
||||
+ conout_found = true;
|
||||
|
||||
status = efi_call_phys4(gop->query_mode, gop,
|
||||
gop->mode->mode, &size, &info);
|
||||
- if (status == EFI_SUCCESS && (!first_gop || pciio)) {
|
||||
+ if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
|
||||
/*
|
||||
- * Apple provide GOPs that are not backed by
|
||||
- * real hardware (they're used to handle
|
||||
- * multiple displays). The workaround is to
|
||||
- * search for a GOP implementing the PCIIO
|
||||
- * protocol, and if one isn't found, to just
|
||||
- * fallback to the first GOP.
|
||||
+ * Systems that use the UEFI Console Splitter may
|
||||
+ * provide multiple GOP devices, not all of which are
|
||||
+ * backed by real hardware. The workaround is to search
|
||||
+ * for a GOP implementing the ConOut protocol, and if
|
||||
+ * one isn't found, to just fall back to the first GOP.
|
||||
*/
|
||||
width = info->horizontal_resolution;
|
||||
height = info->vertical_resolution;
|
||||
@@ -308,10 +427,10 @@
|
||||
pixels_per_scan_line = info->pixels_per_scan_line;
|
||||
|
||||
/*
|
||||
- * Once we've found a GOP supporting PCIIO,
|
||||
+ * Once we've found a GOP supporting ConOut,
|
||||
* don't bother looking any further.
|
||||
*/
|
||||
- if (pciio)
|
||||
+ if (conout_found)
|
||||
break;
|
||||
|
||||
first_gop = gop;
|
||||
@@ -1052,6 +1171,8 @@
|
||||
|
||||
setup_graphics(boot_params);
|
||||
|
@ -196,20 +140,6 @@ diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.c .
|
|||
status = efi_call_phys3(sys_table->boottime->allocate_pool,
|
||||
EFI_LOADER_DATA, sizeof(*gdt),
|
||||
(void **)&gdt);
|
||||
diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.h ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.h
|
||||
--- linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.h 2012-07-21 16:58:29.000000000 -0400
|
||||
+++ ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.h 2012-08-22 15:25:40.530244882 -0400
|
||||
@@ -14,6 +14,10 @@
|
||||
#define EFI_PAGE_SIZE (1UL << EFI_PAGE_SHIFT)
|
||||
#define EFI_READ_CHUNK_SIZE (1024 * 1024)
|
||||
|
||||
+#define EFI_CONSOLE_OUT_DEVICE_GUID \
|
||||
+ EFI_GUID( 0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x0, 0x90, 0x27, \
|
||||
+ 0x3f, 0xc1, 0x4d )
|
||||
+
|
||||
#define PIXEL_RGB_RESERVED_8BIT_PER_COLOR 0
|
||||
#define PIXEL_BGR_RESERVED_8BIT_PER_COLOR 1
|
||||
#define PIXEL_BIT_MASK 2
|
||||
diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/bootparam.h ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/bootparam.h
|
||||
--- linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/bootparam.h 2012-08-22 15:26:32.485522068 -0400
|
||||
+++ ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/bootparam.h 2012-08-22 15:25:40.530244882 -0400
|
||||
|
@ -332,25 +262,19 @@ diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/pci.c ../kernel-3.5.fc
|
|||
diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/rom.c ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/rom.c
|
||||
--- linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/rom.c 2012-07-21 16:58:29.000000000 -0400
|
||||
+++ ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/rom.c 2012-08-22 15:25:40.531244893 -0400
|
||||
@@ -118,11 +118,17 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
|
||||
void __iomem *rom;
|
||||
|
||||
/*
|
||||
+ * Some devices may provide ROMs via a source other than the BAR
|
||||
+ */
|
||||
+ if (pdev->rom && pdev->romlen) {
|
||||
+ *size = pdev->romlen;
|
||||
+ return phys_to_virt(pdev->rom);
|
||||
+ /*
|
||||
* IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy
|
||||
* memory map if the VGA enable bit of the Bridge Control register is
|
||||
* set for embedded VGA.
|
||||
*/
|
||||
- if (res->flags & IORESOURCE_ROM_SHADOW) {
|
||||
+ } else if (res->flags & IORESOURCE_ROM_SHADOW) {
|
||||
@@ -126,6 +126,12 @@
|
||||
/* primary video rom always starts here */
|
||||
start = (loff_t)0xC0000;
|
||||
*size = 0x20000; /* cover C000:0 through E000:0 */
|
||||
+ /*
|
||||
+ * Some devices may provide ROMs via a source other than the BAR
|
||||
+ */
|
||||
+ } else if (pdev->rom && pdev->romlen) {
|
||||
+ *size = pdev->romlen;
|
||||
+ return phys_to_virt(pdev->rom);
|
||||
} else {
|
||||
if (res->flags &
|
||||
(IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) {
|
||||
@@ -219,7 +225,8 @@
|
||||
if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY))
|
||||
return;
|
||||
|
|
2150
kernel.spec
2150
kernel.spec
File diff suppressed because it is too large
Load Diff
|
@ -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.
|
||||
|
|
|
@ -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)];
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
||||
/*
|
4
sources
4
sources
|
@ -1,2 +1,2 @@
|
|||
1a1760420eac802c541a20ab51a093d1 linux-3.6.tar.xz
|
||||
bd4bba74093405887d521309a74c19e9 patch-3.6.11.xz
|
||||
21223369d682bcf44bcdfe1521095983 linux-3.7.tar.xz
|
||||
48f5f530b048e387e978e3e49de7742a patch-3.7.1.xz
|
||||
|
|
|
@ -1,499 +0,0 @@
|
|||
Update team driver to latest net-next.
|
||||
|
||||
Split patches available here:
|
||||
http://people.redhat.com/jpirko/f18_team_update_2/
|
||||
|
||||
Jiri Pirko (4):
|
||||
netlink: add signed types
|
||||
team: add signed 32-bit team option type
|
||||
team: add per port priority option
|
||||
team: add support for queue override by setting queue_id for port
|
||||
|
||||
drivers/net/team/team.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
include/linux/if_team.h | 7 ++
|
||||
include/net/netlink.h | 98 +++++++++++++++++++++++
|
||||
3 files changed, 303 insertions(+), 2 deletions(-)
|
||||
|
||||
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
|
||||
|
||||
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
|
||||
index 87707ab..ba10c46 100644
|
||||
--- a/drivers/net/team/team.c
|
||||
+++ b/drivers/net/team/team.c
|
||||
@@ -658,6 +658,122 @@ static rx_handler_result_t team_handle_frame(struct sk_buff **pskb)
|
||||
}
|
||||
|
||||
|
||||
+/*************************************
|
||||
+ * Multiqueue Tx port select override
|
||||
+ *************************************/
|
||||
+
|
||||
+static int team_queue_override_init(struct team *team)
|
||||
+{
|
||||
+ struct list_head *listarr;
|
||||
+ unsigned int queue_cnt = team->dev->num_tx_queues - 1;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ if (!queue_cnt)
|
||||
+ return 0;
|
||||
+ listarr = kmalloc(sizeof(struct list_head) * queue_cnt, GFP_KERNEL);
|
||||
+ if (!listarr)
|
||||
+ return -ENOMEM;
|
||||
+ team->qom_lists = listarr;
|
||||
+ for (i = 0; i < queue_cnt; i++)
|
||||
+ INIT_LIST_HEAD(listarr++);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void team_queue_override_fini(struct team *team)
|
||||
+{
|
||||
+ kfree(team->qom_lists);
|
||||
+}
|
||||
+
|
||||
+static struct list_head *__team_get_qom_list(struct team *team, u16 queue_id)
|
||||
+{
|
||||
+ return &team->qom_lists[queue_id - 1];
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * note: already called with rcu_read_lock
|
||||
+ */
|
||||
+static bool team_queue_override_transmit(struct team *team, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct list_head *qom_list;
|
||||
+ struct team_port *port;
|
||||
+
|
||||
+ if (!team->queue_override_enabled || !skb->queue_mapping)
|
||||
+ return false;
|
||||
+ qom_list = __team_get_qom_list(team, skb->queue_mapping);
|
||||
+ list_for_each_entry_rcu(port, qom_list, qom_list) {
|
||||
+ if (!team_dev_queue_xmit(team, port, skb))
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static void __team_queue_override_port_del(struct team *team,
|
||||
+ struct team_port *port)
|
||||
+{
|
||||
+ list_del_rcu(&port->qom_list);
|
||||
+ synchronize_rcu();
|
||||
+ INIT_LIST_HEAD(&port->qom_list);
|
||||
+}
|
||||
+
|
||||
+static bool team_queue_override_port_has_gt_prio_than(struct team_port *port,
|
||||
+ struct team_port *cur)
|
||||
+{
|
||||
+ if (port->priority < cur->priority)
|
||||
+ return true;
|
||||
+ if (port->priority > cur->priority)
|
||||
+ return false;
|
||||
+ if (port->index < cur->index)
|
||||
+ return true;
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static void __team_queue_override_port_add(struct team *team,
|
||||
+ struct team_port *port)
|
||||
+{
|
||||
+ struct team_port *cur;
|
||||
+ struct list_head *qom_list;
|
||||
+ struct list_head *node;
|
||||
+
|
||||
+ if (!port->queue_id || !team_port_enabled(port))
|
||||
+ return;
|
||||
+
|
||||
+ qom_list = __team_get_qom_list(team, port->queue_id);
|
||||
+ node = qom_list;
|
||||
+ list_for_each_entry(cur, qom_list, qom_list) {
|
||||
+ if (team_queue_override_port_has_gt_prio_than(port, cur))
|
||||
+ break;
|
||||
+ node = &cur->qom_list;
|
||||
+ }
|
||||
+ list_add_tail_rcu(&port->qom_list, node);
|
||||
+}
|
||||
+
|
||||
+static void __team_queue_override_enabled_check(struct team *team)
|
||||
+{
|
||||
+ struct team_port *port;
|
||||
+ bool enabled = false;
|
||||
+
|
||||
+ list_for_each_entry(port, &team->port_list, list) {
|
||||
+ if (!list_empty(&port->qom_list)) {
|
||||
+ enabled = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (enabled == team->queue_override_enabled)
|
||||
+ return;
|
||||
+ netdev_dbg(team->dev, "%s queue override\n",
|
||||
+ enabled ? "Enabling" : "Disabling");
|
||||
+ team->queue_override_enabled = enabled;
|
||||
+}
|
||||
+
|
||||
+static void team_queue_override_port_refresh(struct team *team,
|
||||
+ struct team_port *port)
|
||||
+{
|
||||
+ __team_queue_override_port_del(team, port);
|
||||
+ __team_queue_override_port_add(team, port);
|
||||
+ __team_queue_override_enabled_check(team);
|
||||
+}
|
||||
+
|
||||
+
|
||||
/****************
|
||||
* Port handling
|
||||
****************/
|
||||
@@ -688,6 +804,7 @@ static void team_port_enable(struct team *team,
|
||||
hlist_add_head_rcu(&port->hlist,
|
||||
team_port_index_hash(team, port->index));
|
||||
team_adjust_ops(team);
|
||||
+ team_queue_override_port_refresh(team, port);
|
||||
if (team->ops.port_enabled)
|
||||
team->ops.port_enabled(team, port);
|
||||
}
|
||||
@@ -716,6 +833,7 @@ static void team_port_disable(struct team *team,
|
||||
hlist_del_rcu(&port->hlist);
|
||||
__reconstruct_port_hlist(team, port->index);
|
||||
port->index = -1;
|
||||
+ team_queue_override_port_refresh(team, port);
|
||||
__team_adjust_ops(team, team->en_port_count - 1);
|
||||
/*
|
||||
* Wait until readers see adjusted ops. This ensures that
|
||||
@@ -881,6 +999,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
|
||||
|
||||
port->dev = port_dev;
|
||||
port->team = team;
|
||||
+ INIT_LIST_HEAD(&port->qom_list);
|
||||
|
||||
port->orig.mtu = port_dev->mtu;
|
||||
err = dev_set_mtu(port_dev, dev->mtu);
|
||||
@@ -1092,6 +1211,49 @@ static int team_user_linkup_en_option_set(struct team *team,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int team_priority_option_get(struct team *team,
|
||||
+ struct team_gsetter_ctx *ctx)
|
||||
+{
|
||||
+ struct team_port *port = ctx->info->port;
|
||||
+
|
||||
+ ctx->data.s32_val = port->priority;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int team_priority_option_set(struct team *team,
|
||||
+ struct team_gsetter_ctx *ctx)
|
||||
+{
|
||||
+ struct team_port *port = ctx->info->port;
|
||||
+
|
||||
+ port->priority = ctx->data.s32_val;
|
||||
+ team_queue_override_port_refresh(team, port);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int team_queue_id_option_get(struct team *team,
|
||||
+ struct team_gsetter_ctx *ctx)
|
||||
+{
|
||||
+ struct team_port *port = ctx->info->port;
|
||||
+
|
||||
+ ctx->data.u32_val = port->queue_id;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int team_queue_id_option_set(struct team *team,
|
||||
+ struct team_gsetter_ctx *ctx)
|
||||
+{
|
||||
+ struct team_port *port = ctx->info->port;
|
||||
+
|
||||
+ if (port->queue_id == ctx->data.u32_val)
|
||||
+ return 0;
|
||||
+ if (ctx->data.u32_val >= team->dev->real_num_tx_queues)
|
||||
+ return -EINVAL;
|
||||
+ port->queue_id = ctx->data.u32_val;
|
||||
+ team_queue_override_port_refresh(team, port);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static const struct team_option team_options[] = {
|
||||
{
|
||||
.name = "mode",
|
||||
@@ -1120,6 +1282,20 @@ static const struct team_option team_options[] = {
|
||||
.getter = team_user_linkup_en_option_get,
|
||||
.setter = team_user_linkup_en_option_set,
|
||||
},
|
||||
+ {
|
||||
+ .name = "priority",
|
||||
+ .type = TEAM_OPTION_TYPE_S32,
|
||||
+ .per_port = true,
|
||||
+ .getter = team_priority_option_get,
|
||||
+ .setter = team_priority_option_set,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "queue_id",
|
||||
+ .type = TEAM_OPTION_TYPE_U32,
|
||||
+ .per_port = true,
|
||||
+ .getter = team_queue_id_option_get,
|
||||
+ .setter = team_queue_id_option_set,
|
||||
+ },
|
||||
};
|
||||
|
||||
static struct lock_class_key team_netdev_xmit_lock_key;
|
||||
@@ -1155,6 +1331,9 @@ static int team_init(struct net_device *dev)
|
||||
for (i = 0; i < TEAM_PORT_HASHENTRIES; i++)
|
||||
INIT_HLIST_HEAD(&team->en_port_hlist[i]);
|
||||
INIT_LIST_HEAD(&team->port_list);
|
||||
+ err = team_queue_override_init(team);
|
||||
+ if (err)
|
||||
+ goto err_team_queue_override_init;
|
||||
|
||||
team_adjust_ops(team);
|
||||
|
||||
@@ -1170,6 +1349,8 @@ static int team_init(struct net_device *dev)
|
||||
return 0;
|
||||
|
||||
err_options_register:
|
||||
+ team_queue_override_fini(team);
|
||||
+err_team_queue_override_init:
|
||||
free_percpu(team->pcpu_stats);
|
||||
|
||||
return err;
|
||||
@@ -1187,6 +1368,7 @@ static void team_uninit(struct net_device *dev)
|
||||
|
||||
__team_change_mode(team, NULL); /* cleanup */
|
||||
__team_options_unregister(team, team_options, ARRAY_SIZE(team_options));
|
||||
+ team_queue_override_fini(team);
|
||||
mutex_unlock(&team->lock);
|
||||
}
|
||||
|
||||
@@ -1216,10 +1398,12 @@ static int team_close(struct net_device *dev)
|
||||
static netdev_tx_t team_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct team *team = netdev_priv(dev);
|
||||
- bool tx_success = false;
|
||||
+ bool tx_success;
|
||||
unsigned int len = skb->len;
|
||||
|
||||
- tx_success = team->ops.transmit(team, skb);
|
||||
+ tx_success = team_queue_override_transmit(team, skb);
|
||||
+ if (!tx_success)
|
||||
+ tx_success = team->ops.transmit(team, skb);
|
||||
if (tx_success) {
|
||||
struct team_pcpu_stats *pcpu_stats;
|
||||
|
||||
@@ -1787,6 +1971,12 @@ static int team_nl_fill_one_option_get(struct sk_buff *skb, struct team *team,
|
||||
nla_put_flag(skb, TEAM_ATTR_OPTION_DATA))
|
||||
goto nest_cancel;
|
||||
break;
|
||||
+ case TEAM_OPTION_TYPE_S32:
|
||||
+ if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_S32))
|
||||
+ goto nest_cancel;
|
||||
+ if (nla_put_s32(skb, TEAM_ATTR_OPTION_DATA, ctx.data.s32_val))
|
||||
+ goto nest_cancel;
|
||||
+ break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
@@ -1975,6 +2165,9 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
|
||||
case NLA_FLAG:
|
||||
opt_type = TEAM_OPTION_TYPE_BOOL;
|
||||
break;
|
||||
+ case NLA_S32:
|
||||
+ opt_type = TEAM_OPTION_TYPE_S32;
|
||||
+ break;
|
||||
default:
|
||||
goto team_put;
|
||||
}
|
||||
@@ -2031,6 +2224,9 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
|
||||
case TEAM_OPTION_TYPE_BOOL:
|
||||
ctx.data.bool_val = attr_data ? true : false;
|
||||
break;
|
||||
+ case TEAM_OPTION_TYPE_S32:
|
||||
+ ctx.data.s32_val = nla_get_s32(attr_data);
|
||||
+ break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
diff --git a/include/linux/if_team.h b/include/linux/if_team.h
|
||||
index 6960fc1..33fcc20 100644
|
||||
--- a/include/linux/if_team.h
|
||||
+++ b/include/linux/if_team.h
|
||||
@@ -67,6 +67,9 @@ struct team_port {
|
||||
struct netpoll *np;
|
||||
#endif
|
||||
|
||||
+ s32 priority; /* lower number ~ higher priority */
|
||||
+ u16 queue_id;
|
||||
+ struct list_head qom_list; /* node in queue override mapping list */
|
||||
long mode_priv[0];
|
||||
};
|
||||
|
||||
@@ -130,6 +133,7 @@ enum team_option_type {
|
||||
TEAM_OPTION_TYPE_STRING,
|
||||
TEAM_OPTION_TYPE_BINARY,
|
||||
TEAM_OPTION_TYPE_BOOL,
|
||||
+ TEAM_OPTION_TYPE_S32,
|
||||
};
|
||||
|
||||
struct team_option_inst_info {
|
||||
@@ -146,6 +150,7 @@ struct team_gsetter_ctx {
|
||||
u32 len;
|
||||
} bin_val;
|
||||
bool bool_val;
|
||||
+ s32 s32_val;
|
||||
} data;
|
||||
struct team_option_inst_info *info;
|
||||
};
|
||||
@@ -197,6 +202,8 @@ struct team {
|
||||
|
||||
const struct team_mode *mode;
|
||||
struct team_mode_ops ops;
|
||||
+ bool queue_override_enabled;
|
||||
+ struct list_head *qom_lists; /* array of queue override mapping lists */
|
||||
long mode_priv[TEAM_MODE_PRIV_LONGS];
|
||||
};
|
||||
|
||||
diff --git a/include/net/netlink.h b/include/net/netlink.h
|
||||
index 785f37a..09175d5 100644
|
||||
--- a/include/net/netlink.h
|
||||
+++ b/include/net/netlink.h
|
||||
@@ -98,6 +98,10 @@
|
||||
* nla_put_u16(skb, type, value) add u16 attribute to skb
|
||||
* nla_put_u32(skb, type, value) add u32 attribute to skb
|
||||
* nla_put_u64(skb, type, value) add u64 attribute to skb
|
||||
+ * nla_put_s8(skb, type, value) add s8 attribute to skb
|
||||
+ * nla_put_s16(skb, type, value) add s16 attribute to skb
|
||||
+ * nla_put_s32(skb, type, value) add s32 attribute to skb
|
||||
+ * nla_put_s64(skb, type, value) add s64 attribute to skb
|
||||
* nla_put_string(skb, type, str) add string attribute to skb
|
||||
* nla_put_flag(skb, type) add flag attribute to skb
|
||||
* nla_put_msecs(skb, type, jiffies) add msecs attribute to skb
|
||||
@@ -121,6 +125,10 @@
|
||||
* nla_get_u16(nla) get payload for a u16 attribute
|
||||
* nla_get_u32(nla) get payload for a u32 attribute
|
||||
* nla_get_u64(nla) get payload for a u64 attribute
|
||||
+ * nla_get_s8(nla) get payload for a s8 attribute
|
||||
+ * nla_get_s16(nla) get payload for a s16 attribute
|
||||
+ * nla_get_s32(nla) get payload for a s32 attribute
|
||||
+ * nla_get_s64(nla) get payload for a s64 attribute
|
||||
* nla_get_flag(nla) return 1 if flag is true
|
||||
* nla_get_msecs(nla) get payload for a msecs attribute
|
||||
*
|
||||
@@ -160,6 +168,10 @@ enum {
|
||||
NLA_NESTED_COMPAT,
|
||||
NLA_NUL_STRING,
|
||||
NLA_BINARY,
|
||||
+ NLA_S8,
|
||||
+ NLA_S16,
|
||||
+ NLA_S32,
|
||||
+ NLA_S64,
|
||||
__NLA_TYPE_MAX,
|
||||
};
|
||||
|
||||
@@ -183,6 +195,8 @@ enum {
|
||||
* NLA_NESTED_COMPAT Minimum length of structure payload
|
||||
* NLA_U8, NLA_U16,
|
||||
* NLA_U32, NLA_U64,
|
||||
+ * NLA_S8, NLA_S16,
|
||||
+ * NLA_S32, NLA_S64,
|
||||
* NLA_MSECS Leaving the length field zero will verify the
|
||||
* given type fits, using it verifies minimum length
|
||||
* just like "All other"
|
||||
@@ -879,6 +893,50 @@ static inline int nla_put_le64(struct sk_buff *skb, int attrtype, __le64 value)
|
||||
}
|
||||
|
||||
/**
|
||||
+ * nla_put_s8 - Add a s8 netlink attribute to a socket buffer
|
||||
+ * @skb: socket buffer to add attribute to
|
||||
+ * @attrtype: attribute type
|
||||
+ * @value: numeric value
|
||||
+ */
|
||||
+static inline int nla_put_s8(struct sk_buff *skb, int attrtype, s8 value)
|
||||
+{
|
||||
+ return nla_put(skb, attrtype, sizeof(s8), &value);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * nla_put_s16 - Add a s16 netlink attribute to a socket buffer
|
||||
+ * @skb: socket buffer to add attribute to
|
||||
+ * @attrtype: attribute type
|
||||
+ * @value: numeric value
|
||||
+ */
|
||||
+static inline int nla_put_s16(struct sk_buff *skb, int attrtype, s16 value)
|
||||
+{
|
||||
+ return nla_put(skb, attrtype, sizeof(s16), &value);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * nla_put_s32 - Add a s32 netlink attribute to a socket buffer
|
||||
+ * @skb: socket buffer to add attribute to
|
||||
+ * @attrtype: attribute type
|
||||
+ * @value: numeric value
|
||||
+ */
|
||||
+static inline int nla_put_s32(struct sk_buff *skb, int attrtype, s32 value)
|
||||
+{
|
||||
+ return nla_put(skb, attrtype, sizeof(s32), &value);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * nla_put_s64 - Add a s64 netlink attribute to a socket buffer
|
||||
+ * @skb: socket buffer to add attribute to
|
||||
+ * @attrtype: attribute type
|
||||
+ * @value: numeric value
|
||||
+ */
|
||||
+static inline int nla_put_s64(struct sk_buff *skb, int attrtype, s64 value)
|
||||
+{
|
||||
+ return nla_put(skb, attrtype, sizeof(s64), &value);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* nla_put_string - Add a string netlink attribute to a socket buffer
|
||||
* @skb: socket buffer to add attribute to
|
||||
* @attrtype: attribute type
|
||||
@@ -994,6 +1052,46 @@ static inline __be64 nla_get_be64(const struct nlattr *nla)
|
||||
}
|
||||
|
||||
/**
|
||||
+ * nla_get_s32 - return payload of s32 attribute
|
||||
+ * @nla: s32 netlink attribute
|
||||
+ */
|
||||
+static inline s32 nla_get_s32(const struct nlattr *nla)
|
||||
+{
|
||||
+ return *(s32 *) nla_data(nla);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * nla_get_s16 - return payload of s16 attribute
|
||||
+ * @nla: s16 netlink attribute
|
||||
+ */
|
||||
+static inline s16 nla_get_s16(const struct nlattr *nla)
|
||||
+{
|
||||
+ return *(s16 *) nla_data(nla);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * nla_get_s8 - return payload of s8 attribute
|
||||
+ * @nla: s8 netlink attribute
|
||||
+ */
|
||||
+static inline s8 nla_get_s8(const struct nlattr *nla)
|
||||
+{
|
||||
+ return *(s8 *) nla_data(nla);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * nla_get_s64 - return payload of s64 attribute
|
||||
+ * @nla: s64 netlink attribute
|
||||
+ */
|
||||
+static inline s64 nla_get_s64(const struct nlattr *nla)
|
||||
+{
|
||||
+ s64 tmp;
|
||||
+
|
||||
+ nla_memcpy(&tmp, nla, sizeof(tmp));
|
||||
+
|
||||
+ return tmp;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* nla_get_flag - return payload of flag attribute
|
||||
* @nla: flag netlink attribute
|
||||
*/
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
|
||||
Backport fixes from linus's tree.
|
||||
|
||||
upstream commits backported:
|
||||
commit 403f43c937d24832b18524f65415c0bbba6b5064
|
||||
team: bcast: convert return value of team_dev_queue_xmit() to bool correctly
|
||||
commit 3ed7147189d2fbe8ac6da95db2fd9d6d52f53ce9
|
||||
team: fix hw_features setup
|
||||
|
||||
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
|
||||
---
|
||||
drivers/net/team/team.c | 4 +++-
|
||||
drivers/net/team/team_mode_broadcast.c | 6 +++---
|
||||
2 files changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
|
||||
index 5d8e1cb..f504773 100644
|
||||
--- a/drivers/net/team/team.c
|
||||
+++ b/drivers/net/team/team.c
|
||||
@@ -1792,10 +1792,12 @@ static void team_setup(struct net_device *dev)
|
||||
|
||||
dev->features |= NETIF_F_LLTX;
|
||||
dev->features |= NETIF_F_GRO;
|
||||
- dev->hw_features = NETIF_F_HW_VLAN_TX |
|
||||
+ dev->hw_features = TEAM_VLAN_FEATURES |
|
||||
+ NETIF_F_HW_VLAN_TX |
|
||||
NETIF_F_HW_VLAN_RX |
|
||||
NETIF_F_HW_VLAN_FILTER;
|
||||
|
||||
+ dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM);
|
||||
dev->features |= dev->hw_features;
|
||||
}
|
||||
|
||||
diff --git a/drivers/net/team/team_mode_broadcast.c b/drivers/net/team/team_mode_broadcast.c
|
||||
index 9db0171..c5db428 100644
|
||||
--- a/drivers/net/team/team_mode_broadcast.c
|
||||
+++ b/drivers/net/team/team_mode_broadcast.c
|
||||
@@ -29,8 +29,8 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb)
|
||||
if (last) {
|
||||
skb2 = skb_clone(skb, GFP_ATOMIC);
|
||||
if (skb2) {
|
||||
- ret = team_dev_queue_xmit(team, last,
|
||||
- skb2);
|
||||
+ ret = !team_dev_queue_xmit(team, last,
|
||||
+ skb2);
|
||||
if (!sum_ret)
|
||||
sum_ret = ret;
|
||||
}
|
||||
@@ -39,7 +39,7 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb)
|
||||
}
|
||||
}
|
||||
if (last) {
|
||||
- ret = team_dev_queue_xmit(team, last, skb);
|
||||
+ ret = !team_dev_queue_xmit(team, last, skb);
|
||||
if (!sum_ret)
|
||||
sum_ret = ret;
|
||||
}
|
||||
--
|
||||
1.7.11.7
|
||||
|
|
@ -1,335 +0,0 @@
|
|||
--- linux-3.6.0-0.rc7.git2.1.fc18.x86_64.orig/drivers/net/team/Kconfig
|
||||
+++ linux-3.6.0-0.rc7.git2.1.fc18.x86_64/drivers/net/team/Kconfig
|
||||
@@ -21,7 +21,7 @@ config NET_TEAM_MODE_BROADCAST
|
||||
---help---
|
||||
Basic mode where packets are transmitted always by all suitable ports.
|
||||
|
||||
- All added ports are setup to have team's mac address.
|
||||
+ All added ports are setup to have team's device address.
|
||||
|
||||
To compile this team mode as a module, choose M here: the module
|
||||
will be called team_mode_broadcast.
|
||||
@@ -33,7 +33,7 @@ config NET_TEAM_MODE_ROUNDROBIN
|
||||
Basic mode where port used for transmitting packets is selected in
|
||||
round-robin fashion using packet counter.
|
||||
|
||||
- All added ports are setup to have team's mac address.
|
||||
+ All added ports are setup to have team's device address.
|
||||
|
||||
To compile this team mode as a module, choose M here: the module
|
||||
will be called team_mode_roundrobin.
|
||||
--- linux-3.6.0-0.rc7.git2.1.fc18.x86_64.orig/drivers/net/team/team.c
|
||||
+++ linux-3.6.0-0.rc7.git2.1.fc18.x86_64/drivers/net/team/team.c
|
||||
@@ -54,29 +54,29 @@ static struct team_port *team_port_get_r
|
||||
}
|
||||
|
||||
/*
|
||||
- * Since the ability to change mac address for open port device is tested in
|
||||
+ * Since the ability to change device address for open port device is tested in
|
||||
* team_port_add, this function can be called without control of return value
|
||||
*/
|
||||
-static int __set_port_mac(struct net_device *port_dev,
|
||||
- const unsigned char *dev_addr)
|
||||
+static int __set_port_dev_addr(struct net_device *port_dev,
|
||||
+ const unsigned char *dev_addr)
|
||||
{
|
||||
struct sockaddr addr;
|
||||
|
||||
- memcpy(addr.sa_data, dev_addr, ETH_ALEN);
|
||||
- addr.sa_family = ARPHRD_ETHER;
|
||||
+ memcpy(addr.sa_data, dev_addr, port_dev->addr_len);
|
||||
+ addr.sa_family = port_dev->type;
|
||||
return dev_set_mac_address(port_dev, &addr);
|
||||
}
|
||||
|
||||
-static int team_port_set_orig_mac(struct team_port *port)
|
||||
+static int team_port_set_orig_dev_addr(struct team_port *port)
|
||||
{
|
||||
- return __set_port_mac(port->dev, port->orig.dev_addr);
|
||||
+ return __set_port_dev_addr(port->dev, port->orig.dev_addr);
|
||||
}
|
||||
|
||||
-int team_port_set_team_mac(struct team_port *port)
|
||||
+int team_port_set_team_dev_addr(struct team_port *port)
|
||||
{
|
||||
- return __set_port_mac(port->dev, port->team->dev->dev_addr);
|
||||
+ return __set_port_dev_addr(port->dev, port->team->dev->dev_addr);
|
||||
}
|
||||
-EXPORT_SYMBOL(team_port_set_team_mac);
|
||||
+EXPORT_SYMBOL(team_port_set_team_dev_addr);
|
||||
|
||||
static void team_refresh_port_linkup(struct team_port *port)
|
||||
{
|
||||
@@ -967,6 +967,8 @@ static struct netpoll_info *team_netpoll
|
||||
#endif
|
||||
|
||||
static void __team_port_change_port_added(struct team_port *port, bool linkup);
|
||||
+static int team_dev_type_check_change(struct net_device *dev,
|
||||
+ struct net_device *port_dev);
|
||||
|
||||
static int team_port_add(struct team *team, struct net_device *port_dev)
|
||||
{
|
||||
@@ -975,9 +977,8 @@ static int team_port_add(struct team *te
|
||||
char *portname = port_dev->name;
|
||||
int err;
|
||||
|
||||
- if (port_dev->flags & IFF_LOOPBACK ||
|
||||
- port_dev->type != ARPHRD_ETHER) {
|
||||
- netdev_err(dev, "Device %s is of an unsupported type\n",
|
||||
+ if (port_dev->flags & IFF_LOOPBACK) {
|
||||
+ netdev_err(dev, "Device %s is loopback device. Loopback devices can't be added as a team port\n",
|
||||
portname);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -988,6 +989,17 @@ static int team_port_add(struct team *te
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
+ if (port_dev->features & NETIF_F_VLAN_CHALLENGED &&
|
||||
+ vlan_uses_dev(dev)) {
|
||||
+ netdev_err(dev, "Device %s is VLAN challenged and team device has VLAN set up\n",
|
||||
+ portname);
|
||||
+ return -EPERM;
|
||||
+ }
|
||||
+
|
||||
+ err = team_dev_type_check_change(dev, port_dev);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
if (port_dev->flags & IFF_UP) {
|
||||
netdev_err(dev, "Device %s is up. Set it down before adding it as a team port\n",
|
||||
portname);
|
||||
@@ -1010,7 +1022,7 @@ static int team_port_add(struct team *te
|
||||
goto err_set_mtu;
|
||||
}
|
||||
|
||||
- memcpy(port->orig.dev_addr, port_dev->dev_addr, ETH_ALEN);
|
||||
+ memcpy(port->orig.dev_addr, port_dev->dev_addr, port_dev->addr_len);
|
||||
|
||||
err = team_port_enter(team, port);
|
||||
if (err) {
|
||||
@@ -1091,7 +1103,7 @@ err_vids_add:
|
||||
|
||||
err_dev_open:
|
||||
team_port_leave(team, port);
|
||||
- team_port_set_orig_mac(port);
|
||||
+ team_port_set_orig_dev_addr(port);
|
||||
|
||||
err_port_enter:
|
||||
dev_set_mtu(port_dev, port->orig.mtu);
|
||||
@@ -1129,7 +1141,7 @@ static int team_port_del(struct team *te
|
||||
vlan_vids_del_by_dev(port_dev, dev);
|
||||
dev_close(port_dev);
|
||||
team_port_leave(team, port);
|
||||
- team_port_set_orig_mac(port);
|
||||
+ team_port_set_orig_dev_addr(port);
|
||||
dev_set_mtu(port_dev, port->orig.mtu);
|
||||
synchronize_rcu();
|
||||
kfree(port);
|
||||
@@ -1480,17 +1492,18 @@ static void team_set_rx_mode(struct net_
|
||||
|
||||
static int team_set_mac_address(struct net_device *dev, void *p)
|
||||
{
|
||||
+ struct sockaddr *addr = p;
|
||||
struct team *team = netdev_priv(dev);
|
||||
struct team_port *port;
|
||||
- int err;
|
||||
|
||||
- err = eth_mac_addr(dev, p);
|
||||
- if (err)
|
||||
- return err;
|
||||
+ if (dev->type == ARPHRD_ETHER && !is_valid_ether_addr(addr->sa_data))
|
||||
+ return -EADDRNOTAVAIL;
|
||||
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
|
||||
+ dev->addr_assign_type &= ~NET_ADDR_RANDOM;
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(port, &team->port_list, list)
|
||||
- if (team->ops.port_change_mac)
|
||||
- team->ops.port_change_mac(team, port);
|
||||
+ if (team->ops.port_change_dev_addr)
|
||||
+ team->ops.port_change_dev_addr(team, port);
|
||||
rcu_read_unlock();
|
||||
return 0;
|
||||
}
|
||||
@@ -1721,6 +1734,45 @@ static const struct net_device_ops team_
|
||||
* rt netlink interface
|
||||
***********************/
|
||||
|
||||
+static void team_setup_by_port(struct net_device *dev,
|
||||
+ struct net_device *port_dev)
|
||||
+{
|
||||
+ dev->header_ops = port_dev->header_ops;
|
||||
+ dev->type = port_dev->type;
|
||||
+ dev->hard_header_len = port_dev->hard_header_len;
|
||||
+ dev->addr_len = port_dev->addr_len;
|
||||
+ dev->mtu = port_dev->mtu;
|
||||
+ memcpy(dev->broadcast, port_dev->broadcast, port_dev->addr_len);
|
||||
+ memcpy(dev->dev_addr, port_dev->dev_addr, port_dev->addr_len);
|
||||
+ dev->addr_assign_type &= ~NET_ADDR_RANDOM;
|
||||
+}
|
||||
+
|
||||
+static int team_dev_type_check_change(struct net_device *dev,
|
||||
+ struct net_device *port_dev)
|
||||
+{
|
||||
+ struct team *team = netdev_priv(dev);
|
||||
+ char *portname = port_dev->name;
|
||||
+ int err;
|
||||
+
|
||||
+ if (dev->type == port_dev->type)
|
||||
+ return 0;
|
||||
+ if (!list_empty(&team->port_list)) {
|
||||
+ netdev_err(dev, "Device %s is of different type\n", portname);
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+ err = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev);
|
||||
+ err = notifier_to_errno(err);
|
||||
+ if (err) {
|
||||
+ netdev_err(dev, "Refused to change device type\n");
|
||||
+ return err;
|
||||
+ }
|
||||
+ dev_uc_flush(dev);
|
||||
+ dev_mc_flush(dev);
|
||||
+ team_setup_by_port(dev, port_dev);
|
||||
+ call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void team_setup(struct net_device *dev)
|
||||
{
|
||||
ether_setup(dev);
|
||||
@@ -2442,7 +2494,7 @@ static void __team_options_change_check(
|
||||
list_add_tail(&opt_inst->tmp_list, &sel_opt_inst_list);
|
||||
}
|
||||
err = team_nl_send_event_options_get(team, &sel_opt_inst_list);
|
||||
- if (err)
|
||||
+ if (err && err != -ESRCH)
|
||||
netdev_warn(team->dev, "Failed to send options change via netlink (err %d)\n",
|
||||
err);
|
||||
}
|
||||
@@ -2471,9 +2523,9 @@ static void __team_port_change_send(stru
|
||||
|
||||
send_event:
|
||||
err = team_nl_send_event_port_list_get(port->team);
|
||||
- if (err)
|
||||
- netdev_warn(port->team->dev, "Failed to send port change of device %s via netlink\n",
|
||||
- port->dev->name);
|
||||
+ if (err && err != -ESRCH)
|
||||
+ netdev_warn(port->team->dev, "Failed to send port change of device %s via netlink (err %d)\n",
|
||||
+ port->dev->name, err);
|
||||
|
||||
}
|
||||
|
||||
--- linux-3.6.0-0.rc7.git2.1.fc18.x86_64.orig/drivers/net/team/team_mode_broadcast.c
|
||||
+++ linux-3.6.0-0.rc7.git2.1.fc18.x86_64/drivers/net/team/team_mode_broadcast.c
|
||||
@@ -48,18 +48,18 @@ static bool bc_transmit(struct team *tea
|
||||
|
||||
static int bc_port_enter(struct team *team, struct team_port *port)
|
||||
{
|
||||
- return team_port_set_team_mac(port);
|
||||
+ return team_port_set_team_dev_addr(port);
|
||||
}
|
||||
|
||||
-static void bc_port_change_mac(struct team *team, struct team_port *port)
|
||||
+static void bc_port_change_dev_addr(struct team *team, struct team_port *port)
|
||||
{
|
||||
- team_port_set_team_mac(port);
|
||||
+ team_port_set_team_dev_addr(port);
|
||||
}
|
||||
|
||||
static const struct team_mode_ops bc_mode_ops = {
|
||||
.transmit = bc_transmit,
|
||||
.port_enter = bc_port_enter,
|
||||
- .port_change_mac = bc_port_change_mac,
|
||||
+ .port_change_dev_addr = bc_port_change_dev_addr,
|
||||
};
|
||||
|
||||
static const struct team_mode bc_mode = {
|
||||
--- linux-3.6.0-0.rc7.git2.1.fc18.x86_64.orig/drivers/net/team/team_mode_roundrobin.c
|
||||
+++ linux-3.6.0-0.rc7.git2.1.fc18.x86_64/drivers/net/team/team_mode_roundrobin.c
|
||||
@@ -66,18 +66,18 @@ drop:
|
||||
|
||||
static int rr_port_enter(struct team *team, struct team_port *port)
|
||||
{
|
||||
- return team_port_set_team_mac(port);
|
||||
+ return team_port_set_team_dev_addr(port);
|
||||
}
|
||||
|
||||
-static void rr_port_change_mac(struct team *team, struct team_port *port)
|
||||
+static void rr_port_change_dev_addr(struct team *team, struct team_port *port)
|
||||
{
|
||||
- team_port_set_team_mac(port);
|
||||
+ team_port_set_team_dev_addr(port);
|
||||
}
|
||||
|
||||
static const struct team_mode_ops rr_mode_ops = {
|
||||
.transmit = rr_transmit,
|
||||
.port_enter = rr_port_enter,
|
||||
- .port_change_mac = rr_port_change_mac,
|
||||
+ .port_change_dev_addr = rr_port_change_dev_addr,
|
||||
};
|
||||
|
||||
static const struct team_mode rr_mode = {
|
||||
--- linux-3.6.0-0.rc7.git2.1.fc18.x86_64.orig/include/linux/if_team.h
|
||||
+++ linux-3.6.0-0.rc7.git2.1.fc18.x86_64/include/linux/if_team.h
|
||||
@@ -108,7 +108,7 @@ struct team_mode_ops {
|
||||
bool (*transmit)(struct team *team, struct sk_buff *skb);
|
||||
int (*port_enter)(struct team *team, struct team_port *port);
|
||||
void (*port_leave)(struct team *team, struct team_port *port);
|
||||
- void (*port_change_mac)(struct team *team, struct team_port *port);
|
||||
+ void (*port_change_dev_addr)(struct team *team, struct team_port *port);
|
||||
void (*port_enabled)(struct team *team, struct team_port *port);
|
||||
void (*port_disabled)(struct team *team, struct team_port *port);
|
||||
};
|
||||
@@ -238,7 +238,7 @@ static inline struct team_port *team_get
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-extern int team_port_set_team_mac(struct team_port *port);
|
||||
+extern int team_port_set_team_dev_addr(struct team_port *port);
|
||||
extern int team_options_register(struct team *team,
|
||||
const struct team_option *option,
|
||||
size_t option_count);
|
||||
--- linux-3.6.0-0.rc7.git2.1.fc18.x86_64.orig/include/linux/if_vlan.h
|
||||
+++ linux-3.6.0-0.rc7.git2.1.fc18.x86_64/include/linux/if_vlan.h
|
||||
@@ -74,8 +74,6 @@ static inline struct vlan_ethhdr *vlan_e
|
||||
/* found in socket.c */
|
||||
extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
|
||||
|
||||
-struct vlan_info;
|
||||
-
|
||||
static inline int is_vlan_dev(struct net_device *dev)
|
||||
{
|
||||
return dev->priv_flags & IFF_802_1Q_VLAN;
|
||||
@@ -101,6 +99,8 @@ extern int vlan_vids_add_by_dev(struct n
|
||||
const struct net_device *by_dev);
|
||||
extern void vlan_vids_del_by_dev(struct net_device *dev,
|
||||
const struct net_device *by_dev);
|
||||
+
|
||||
+extern bool vlan_uses_dev(const struct net_device *dev);
|
||||
#else
|
||||
static inline struct net_device *
|
||||
__vlan_find_dev_deep(struct net_device *real_dev, u16 vlan_id)
|
||||
@@ -151,6 +151,11 @@ static inline void vlan_vids_del_by_dev(
|
||||
const struct net_device *by_dev)
|
||||
{
|
||||
}
|
||||
+
|
||||
+static inline bool vlan_uses_dev(const struct net_device *dev)
|
||||
+{
|
||||
+ return false;
|
||||
+}
|
||||
#endif
|
||||
|
||||
/**
|
||||
--- linux-3.6.0-0.rc7.git2.1.fc18.x86_64.orig/net/8021q/vlan_core.c
|
||||
+++ linux-3.6.0-0.rc7.git2.1.fc18.x86_64/net/8021q/vlan_core.c
|
||||
@@ -368,3 +368,9 @@ void vlan_vids_del_by_dev(struct net_dev
|
||||
vlan_vid_del(dev, vid_info->vid);
|
||||
}
|
||||
EXPORT_SYMBOL(vlan_vids_del_by_dev);
|
||||
+
|
||||
+bool vlan_uses_dev(const struct net_device *dev)
|
||||
+{
|
||||
+ return rtnl_dereference(dev->vlan_info) ? true : false;
|
||||
+}
|
||||
+EXPORT_SYMBOL(vlan_uses_dev);
|
File diff suppressed because it is too large
Load Diff
|
@ -64,7 +64,7 @@ Signed-off-by: Adam Jackson <ajax@redhat.com>
|
|||
drivers/tty/vt/vt_ioctl.c | 13 +++++++++++++
|
||||
include/linux/kbd_kern.h | 6 +++---
|
||||
include/linux/vt_kern.h | 2 ++
|
||||
include/linux/kd.h | 5 +++++
|
||||
include/uapi/linux/kd.h | 5 +++++
|
||||
5 files changed, 56 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
|
||||
|
@ -222,10 +222,10 @@ index 50ae7d0..a886915 100644
|
|||
extern int vt_do_kdgkbmode(int console);
|
||||
extern int vt_do_kdgkbmeta(int console);
|
||||
extern void vt_reset_unicode(int console);
|
||||
diff --git a/include/linux/kd.h b/include/linux/kd.h
|
||||
diff --git a/include/uapi/linux/kd.h b/include/uapi/linux/kd.h
|
||||
index 87b7cc4..c3de63c 100644
|
||||
--- a/include/linux/kd.h
|
||||
+++ b/include/linux/kd.h
|
||||
--- a/include/uapi/linux/kd.h
|
||||
+++ b/include/uapi/linux/kd.h
|
||||
@@ -81,6 +81,7 @@ struct unimapinit {
|
||||
#define K_XLATE 0x01
|
||||
#define K_MEDIUMRAW 0x02
|
||||
|
|
Loading…
Reference in New Issue