From bf8beb252024ff1812ad464e2210239c45c93c3d Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Jan 18 2013 17:28:28 +0000 Subject: Linux v3.7.3 --- diff --git a/0001-ACPI-sony-laptop-do-proper-memcpy-for-ACPI_TYPE_INTE.patch b/0001-ACPI-sony-laptop-do-proper-memcpy-for-ACPI_TYPE_INTE.patch deleted file mode 100644 index 857c73c..0000000 --- a/0001-ACPI-sony-laptop-do-proper-memcpy-for-ACPI_TYPE_INTE.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 690b1ad9d2032d6f2565d44f6564590d47835ae8 Mon Sep 17 00:00:00 2001 -From: Zhang Rui -Date: Thu, 29 Nov 2012 01:30:43 +0800 -Subject: [PATCH 1/2] ACPI sony-laptop: do proper memcpy for ACPI_TYPE_INTEGER - acpi_object - -the return value of __call_snc_method can either be -an ACPI_TYPE_BUFFER object or a ACPI_TYPE_INTEGER object. -do proper memcpy for ACPI_TYPE_INTEGER object. - -https://bugzilla.kernel.org/show_bug.cgi?id=50111 - -Signed-off-by: Zhang Rui ---- - drivers/platform/x86/sony-laptop.c | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - -diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c -index daaddec..92e0da2 100644 ---- a/drivers/platform/x86/sony-laptop.c -+++ b/drivers/platform/x86/sony-laptop.c -@@ -792,20 +792,19 @@ static int sony_nc_buffer_call(acpi_handle handle, char *name, u64 *value, - if (!object) - return -EINVAL; - -- if (object->type == ACPI_TYPE_BUFFER) -+ if (object->type == ACPI_TYPE_BUFFER) { - len = MIN(buflen, object->buffer.length); -- -- else if (object->type == ACPI_TYPE_INTEGER) -+ memcpy(buffer, object->buffer.pointer, len); -+ } else if (object->type == ACPI_TYPE_INTEGER) { - len = MIN(buflen, sizeof(object->integer.value)); -- -- else { -+ memcpy(buffer, (void *)&object->integer.value, len); -+ } else { - pr_warn("Invalid acpi_object: expected 0x%x got 0x%x\n", - ACPI_TYPE_BUFFER, object->type); - kfree(object); - return -EINVAL; - } - -- memcpy(buffer, object->buffer.pointer, len); - kfree(object); - return 0; - } --- -1.7.9.5 - diff --git a/0001-ext4-ext4_inode_info-diet.patch b/0001-ext4-ext4_inode_info-diet.patch deleted file mode 100644 index c7858ec..0000000 --- a/0001-ext4-ext4_inode_info-diet.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 50b61634cf8d09f9ef334919b859735d381cbe39 Mon Sep 17 00:00:00 2001 -From: Dmitry Monakhov -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 -Reviewed-by: Jan Kara -Signed-off-by: Dmitry Monakhov -Signed-off-by: "Theodore Ts'o" -(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 - diff --git a/0002-ext4-give-i_aiodio_unwritten-a-more-appropriate-name.patch b/0002-ext4-give-i_aiodio_unwritten-a-more-appropriate-name.patch deleted file mode 100644 index cfd13f3..0000000 --- a/0002-ext4-give-i_aiodio_unwritten-a-more-appropriate-name.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 027d1aa67e32c2c80851105c6d962f3db46eb476 Mon Sep 17 00:00:00 2001 -From: Dmitry Monakhov -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 -Signed-off-by: Dmitry Monakhov -Signed-off-by: "Theodore Ts'o" -(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 - diff --git a/0003-ext4-fix-unwritten-counter-leakage.patch b/0003-ext4-fix-unwritten-counter-leakage.patch deleted file mode 100644 index 2f1d0d8..0000000 --- a/0003-ext4-fix-unwritten-counter-leakage.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 6a0e905bb7320571ed5fdd2d5efa3d642630b4f7 Mon Sep 17 00:00:00 2001 -From: Dmitry Monakhov -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 -Signed-off-by: Dmitry Monakhov -Signed-off-by: "Theodore Ts'o" -(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 - diff --git a/0004-ext4-completed_io-locking-cleanup.patch b/0004-ext4-completed_io-locking-cleanup.patch deleted file mode 100644 index a358a79..0000000 --- a/0004-ext4-completed_io-locking-cleanup.patch +++ /dev/null @@ -1,520 +0,0 @@ -From e23394806df0768ed2dac87484590d2f3a730d55 Mon Sep 17 00:00:00 2001 -From: Dmitry Monakhov -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 -Signed-off-by: "Theodore Ts'o" -(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 - --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 - diff --git a/0005-ext4-serialize-dio-nonlocked-reads-with-defrag-worke.patch b/0005-ext4-serialize-dio-nonlocked-reads-with-defrag-worke.patch deleted file mode 100644 index cf53b8d..0000000 --- a/0005-ext4-serialize-dio-nonlocked-reads-with-defrag-worke.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 994f567b2e99c82913a279ff438269c771b68a4b Mon Sep 17 00:00:00 2001 -From: Dmitry Monakhov -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 -Signed-off-by: Dmitry Monakhov -Signed-off-by: "Theodore Ts'o" -(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 - diff --git a/0006-ext4-serialize-unlocked-dio-reads-with-truncate.patch b/0006-ext4-serialize-unlocked-dio-reads-with-truncate.patch deleted file mode 100644 index bddcc60..0000000 --- a/0006-ext4-serialize-unlocked-dio-reads-with-truncate.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 4c4679fc02744ec3955e88faf5e8b6844fa8cbd3 Mon Sep 17 00:00:00 2001 -From: Dmitry Monakhov -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 -Signed-off-by: Dmitry Monakhov -Signed-off-by: "Theodore Ts'o" -(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 - diff --git a/0007-ext4-endless-truncate-due-to-nonlocked-dio-readers.patch b/0007-ext4-endless-truncate-due-to-nonlocked-dio-readers.patch deleted file mode 100644 index 768215f..0000000 --- a/0007-ext4-endless-truncate-due-to-nonlocked-dio-readers.patch +++ /dev/null @@ -1,41 +0,0 @@ -From ab7b8a329e12369d58e5fa59ba2e2c90370f12ef Mon Sep 17 00:00:00 2001 -From: Dmitry Monakhov -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 -Signed-off-by: Dmitry Monakhov -Signed-off-by: "Theodore Ts'o" -(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 - diff --git a/0008-ext4-serialize-truncate-with-owerwrite-DIO-workers.patch b/0008-ext4-serialize-truncate-with-owerwrite-DIO-workers.patch deleted file mode 100644 index c7733ed..0000000 --- a/0008-ext4-serialize-truncate-with-owerwrite-DIO-workers.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 69e4026a2d104ffcf1b935bc889f8abcbfbb29ec Mon Sep 17 00:00:00 2001 -From: Dmitry Monakhov -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 -Signed-off-by: Dmitry Monakhov -Signed-off-by: "Theodore Ts'o" -(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 - diff --git a/0009-ext4-punch_hole-should-wait-for-DIO-writers.patch b/0009-ext4-punch_hole-should-wait-for-DIO-writers.patch deleted file mode 100644 index 4d76366..0000000 --- a/0009-ext4-punch_hole-should-wait-for-DIO-writers.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 71a6398a4b59ddcf920dfb68872b5a771c606e3a Mon Sep 17 00:00:00 2001 -From: Dmitry Monakhov -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 -Signed-off-by: "Theodore Ts'o" -(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 - diff --git a/0010-ext4-fix-ext_remove_space-for-punch_hole-case.patch b/0010-ext4-fix-ext_remove_space-for-punch_hole-case.patch deleted file mode 100644 index d161bb7..0000000 --- a/0010-ext4-fix-ext_remove_space-for-punch_hole-case.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 66d08dd92b82dabfd64853aa4edde1547fdf9ef7 Mon Sep 17 00:00:00 2001 -From: Dmitry Monakhov -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 -Signed-off-by: "Theodore Ts'o" -(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 - diff --git a/0011-ext4-fix-ext4_flush_completed_IO-wait-semantics.patch b/0011-ext4-fix-ext4_flush_completed_IO-wait-semantics.patch deleted file mode 100644 index 517b201..0000000 --- a/0011-ext4-fix-ext4_flush_completed_IO-wait-semantics.patch +++ /dev/null @@ -1,176 +0,0 @@ -From ca6d3910cbf8854f3f3b9846391f669733899101 Mon Sep 17 00:00:00 2001 -From: Dmitry Monakhov -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 -Signed-off-by: "Theodore Ts'o" -Reviewed-by: Jan Kara -(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 - diff --git a/0012-ext4-serialize-fallocate-with-ext4_convert_unwritten.patch b/0012-ext4-serialize-fallocate-with-ext4_convert_unwritten.patch deleted file mode 100644 index 3fcaef1..0000000 --- a/0012-ext4-serialize-fallocate-with-ext4_convert_unwritten.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 9f00d109efeaf4d12d56c8e46cd13af80e344f97 Mon Sep 17 00:00:00 2001 -From: Dmitry Monakhov -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 -Signed-off-by: "Theodore Ts'o" -(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 - diff --git a/ACPI-do-not-use-Lid-and-Sleep-button-for-S5-wakeup.patch b/ACPI-do-not-use-Lid-and-Sleep-button-for-S5-wakeup.patch deleted file mode 100644 index f6e997c..0000000 --- a/ACPI-do-not-use-Lid-and-Sleep-button-for-S5-wakeup.patch +++ /dev/null @@ -1,46 +0,0 @@ -From b7e383046c2c7c13ad928cd7407eafff758ddd4b Mon Sep 17 00:00:00 2001 -From: Zhang Rui -Date: Tue, 4 Dec 2012 23:23:16 +0100 -Subject: [PATCH] ACPI : do not use Lid and Sleep button for S5 wakeup - -When system enters power off, the _PSW of Lid device is enabled. -But this may cause the system to reboot instead of power off. - -A proper way to fix this is to always disable lid wakeup capability for S5. - -References: https://bugzilla.kernel.org/show_bug.cgi?id=35262 -Signed-off-by: Zhang Rui -Signed-off-by: Rafael J. Wysocki ---- - drivers/acpi/scan.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c -index d0b38ab..bd523bf 100644 ---- a/drivers/acpi/scan.c -+++ b/drivers/acpi/scan.c -@@ -917,8 +917,8 @@ acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, - static void acpi_bus_set_run_wake_flags(struct acpi_device *device) - { - struct acpi_device_id button_device_ids[] = { -- {"PNP0C0D", 0}, - {"PNP0C0C", 0}, -+ {"PNP0C0D", 0}, - {"PNP0C0E", 0}, - {"", 0}, - }; -@@ -930,6 +930,11 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) - /* Power button, Lid switch always enable wakeup */ - if (!acpi_match_device_ids(device, button_device_ids)) { - device->wakeup.flags.run_wake = 1; -+ if (!acpi_match_device_ids(device, &button_device_ids[1])) { -+ /* Do not use Lid/sleep button for S5 wakeup */ -+ if (device->wakeup.sleep_state == ACPI_STATE_S5) -+ device->wakeup.sleep_state = ACPI_STATE_S4; -+ } - device_set_wakeup_capable(&device->dev, true); - return; - } --- -1.8.0.1 - diff --git a/Bluetooth-Add-support-for-BCM20702A0.patch b/Bluetooth-Add-support-for-BCM20702A0.patch deleted file mode 100644 index 73f00fc..0000000 --- a/Bluetooth-Add-support-for-BCM20702A0.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 7f198e1cc6d4fda9c84c0da4fc3aafb441342f78 Mon Sep 17 00:00:00 2001 -From: Jaroslav Resler -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 -Signed-off-by: Gustavo Padovan ---- - 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 -Date: Fri, 9 Nov 2012 16:39:48 -0700 -Subject: [PATCH 2/2] Bluetooth: Add support for BCM20702A0 [0b05, 17b5] - -Vendor-specific ID for BCM20702A0. -Support for bluetooth over Asus Wi-Fi GO!, included with Asus P8Z77-V -Deluxe. - -T: Bus=07 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 -D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 -P: Vendor=0b05 ProdID=17b5 Rev=01.12 -S: Manufacturer=Broadcom Corp -S: Product=BCM20702A0 -S: SerialNumber=94DBC98AC113 -C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=0mA -I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none) -I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none) -I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) -I: If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none) - -Cc: stable@vger.kernel.org -Signed-off-by: Jeff Cook -Signed-off-by: Gustavo Padovan ---- - drivers/bluetooth/btusb.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c -index b167944..6dc44ff 100644 ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -96,6 +96,7 @@ static struct usb_device_id btusb_table[] = { - { USB_DEVICE(0x0c10, 0x0000) }, - - /* Broadcom BCM20702A0 */ -+ { USB_DEVICE(0x0b05, 0x17b5) }, - { USB_DEVICE(0x04ca, 0x2003) }, - { USB_DEVICE(0x0489, 0xe042) }, - { USB_DEVICE(0x413c, 0x8197) }, --- -1.8.0 - diff --git a/SCSI-mvsas-Fix-oops-when-ata-commond-timeout.patch b/SCSI-mvsas-Fix-oops-when-ata-commond-timeout.patch deleted file mode 100644 index 0d83e8d..0000000 --- a/SCSI-mvsas-Fix-oops-when-ata-commond-timeout.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 95ab000388974d8ffef8257306b4be6e8778b768 Mon Sep 17 00:00:00 2001 -From: Jianpeng Ma -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: [] _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:[] [] -_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] [] complete+0x23/0x60 -[ 511.712115] [] mvs_tmf_timedout+0x18/0x20 [mvsas] -[ 511.712119] [] mvs_slot_complete+0x765/0x7d0 -[mvsas] -[ 511.712125] [] sas_scsi_recover_host+0x55d/0xdb0 -[libsas] -[ 511.712128] [] ? idle_balance+0xe0/0x130 -[ 511.712133] [] scsi_error_handler+0xcc/0x470 -[ 511.712136] [] ? __schedule+0x370/0x730 -[ 511.712139] [] ? __wake_up_common+0x58/0x90 -[ 511.712142] [] ? scsi_eh_get_sense+0x110/0x110 -[ 511.712146] [] kthread+0x8e/0xa0 -[ 511.712150] [] kernel_thread_helper+0x4/0x10 -[ 511.712153] [] ? flush_kthread_work+0x120/0x120 -[ 511.712156] [] ? 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 66 0f c1 17 0f b6 ce 38 d1 74 11 0f 1f 84 00 00 00 00 00 f3 -[ 511.712191] RIP [] _raw_spin_lock_irqsave+0xc/0x30 -[ 511.712194] RSP -[ 511.712196] CR2: 0000000000000058 -[ 511.712198] ---[ end trace a781c7b1e65db92c ]--- - -Signed-off-by: Jianpeng Ma -Signed-off-by: James Bottomley ---- - 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 - diff --git a/aoe-remove-extra-bdi_init.patch b/aoe-remove-extra-bdi_init.patch deleted file mode 100644 index 7275d53..0000000 --- a/aoe-remove-extra-bdi_init.patch +++ /dev/null @@ -1,78 +0,0 @@ -Lines: 75 - -On Thu, Jan 03, 2013 at 12:15:35PM -0600, Ed Cashin wrote: -... -> >>>>> On Jan 3, 2013, at 8:25 AM, Josh Boyer wrote: -... -> >>>>>> [699170.611997] aoe: AoE v47 initialised. -... -> >>>>>> [699231.308319] WARNING: at lib/list_debug.c:62 __list_del_entry+0x82/0xd0() -> >>>>>> [699231.312031] Hardware name: S5000VSA -> >>>>>> [699231.315658] list_del corruption. next->prev should be ffff880009fa37e8, but was ffffffff81c79c00 -> >>>>>> [699231.319352] Modules linked in: aoe(-) ip6table_filter ip6_tables ebtable_nat ebtables lockd sunrpc bridge 8021q garp stp llc vfat fat binfmt_misc iTCO_wdt iTCO_vendor_support vhost_net lpc_ich radeon tun macvtap mfd_core serio_raw coretemp i2c_algo_bit ttm i5000_edac macvlan drm_kms_helper e1000e edac_core microcode i5k_amb shpchp i2c_i801 drm kvm_intel i2c_core kvm ioatdma dca raid1 -> >>>>>> [699231.336259] Pid: 8584, comm: modprobe Not tainted 3.6.11-1.fc17.x86_64 #1 -> >>>>>> [699231.340561] Call Trace: -> >>>>>> [699231.344865] [] warn_slowpath_common+0x7f/0xc0 -> >>>>>> [699231.349212] [] warn_slowpath_fmt+0x46/0x50 -> >>>>>> [699231.353595] [] __list_del_entry+0x82/0xd0 -> >>>>>> [699231.357954] [] list_del+0x11/0x40 -> >>>>>> [699231.362319] [] percpu_counter_destroy+0x28/0x50 -> >>>>>> [699231.366712] [] bdi_destroy+0x43/0x140 -> >>>>>> [699231.371127] [] blk_release_queue+0x8c/0xc0 -> >>>>>> [699231.375454] [] kobject_cleanup+0x82/0x1b0 -> >>>>>> [699231.379675] [] kobject_put+0x2b/0x60 -> >>>>>> [699231.383851] [] blk_put_queue+0x15/0x20 -> >>>>>> [699231.387899] [] blk_cleanup_queue+0xc9/0xe0 -> >>>>>> [699231.391794] [] aoedev_freedev+0x135/0x150 [aoe] -> >>>>>> [699231.395668] [] aoedev_exit+0x65/0x80 [aoe] -> >>>>>> [699231.399493] [] aoe_exit+0x2e/0x40 [aoe] -> >>>>>> [699231.403273] [] sys_delete_module+0x16e/0x2d0 -> >>>>>> [699231.407119] [] ? __schedule+0x3c6/0x7a0 -> >>>>>> [699231.411050] [] ? sys_write+0x4a/0x90 -> >>>>>> [699231.415033] [] system_call_fastpath+0x16/0x1b -> >>>>>> [699231.419117] ---[ end trace 9e1558af1964b569 ]--- -> >>>>>> [699231.423248] ------------[ cut here ]------------ - -The blk_alloc_queue has already done a bdi_init, so do not bdi_init again in -aoeblk_gdalloc. - -The patch below applies to v3.5.6, with its v47 aoe driver. On my system it -eliminates the list_del corruption messages. - -It updates VERSION for convenience during testing. - -diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h -index db195ab..2ccb9e2 100644 ---- a/drivers/block/aoe/aoe.h -+++ b/drivers/block/aoe/aoe.h -@@ -1,5 +1,5 @@ - /* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */ --#define VERSION "47" -+#define VERSION "47nobdi1" - #define AOE_MAJOR 152 - #define DEVICE_NAME "aoe" - -diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c -index 321de7b..7eca463 100644 ---- a/drivers/block/aoe/aoeblk.c -+++ b/drivers/block/aoe/aoeblk.c -@@ -276,8 +276,6 @@ aoeblk_gdalloc(void *vp) - goto err_mempool; - blk_queue_make_request(d->blkq, aoeblk_make_request); - d->blkq->backing_dev_info.name = "aoe"; -- if (bdi_init(&d->blkq->backing_dev_info)) -- goto err_blkq; - spin_lock_irqsave(&d->lock, flags); - gd->major = AOE_MAJOR; - gd->first_minor = d->sysminor * AOE_PARTITIONS; -@@ -298,9 +296,6 @@ aoeblk_gdalloc(void *vp) - aoedisk_add_sysfs(d); - return; - --err_blkq: -- blk_cleanup_queue(d->blkq); -- d->blkq = NULL; - err_mempool: - mempool_destroy(d->bufpool); - err_disk: - diff --git a/arm-fix_radio_shark.patch b/arm-fix_radio_shark.patch deleted file mode 100644 index 63296a9..0000000 --- a/arm-fix_radio_shark.patch +++ /dev/null @@ -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" diff --git a/arm-highbank-sata-fix.patch b/arm-highbank-sata-fix.patch deleted file mode 100644 index fda7b21..0000000 --- a/arm-highbank-sata-fix.patch +++ /dev/null @@ -1,599 +0,0 @@ -From: Mark Langsdorf -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 -Signed-off-by: Rob Herring -Signed-off-by: Jeff Garzik ---- - -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 : - - reg : - -+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 . -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#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 "); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("sata:highbank"); diff --git a/block-fix-a-crash-when-block-device-is.patch b/block-fix-a-crash-when-block-device-is.patch deleted file mode 100644 index af99283..0000000 --- a/block-fix-a-crash-when-block-device-is.patch +++ /dev/null @@ -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 -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 - Signed-off-by: Jens Axboe - -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, diff --git a/blockdev-turn-a-rw-semaphore-into-a-percpu-rw-sem.patch b/blockdev-turn-a-rw-semaphore-into-a-percpu-rw-sem.patch deleted file mode 100644 index 82caa6b..0000000 --- a/blockdev-turn-a-rw-semaphore-into-a-percpu-rw-sem.patch +++ /dev/null @@ -1,290 +0,0 @@ -blockdev: turn a rw semaphore into a percpu rw semaphore - -commit 62ac665ff9fc07497ca524bd20d6a96893d11071 -Author: Mikulas Patocka -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 - Signed-off-by: Jens Axboe - -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 . -+The code was written by Mikulas Patocka -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 - #include - #include -+#include - - #include - -@@ -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 -+#include -+#include -+#include -+ -+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 diff --git a/config-arm-generic b/config-arm-generic index 107268e..89fc435 100644 --- a/config-arm-generic +++ b/config-arm-generic @@ -12,6 +12,7 @@ CONFIG_AEABI=y CONFIG_OABI_COMPAT=y CONFIG_VFP=y CONFIG_ARM_UNWIND=y +# CONFIG_ARCH_MULTI_V7 is not set CONFIG_SMP=y CONFIG_NR_CPUS=4 @@ -27,6 +28,7 @@ CONFIG_FPE_FASTFPE=y CONFIG_HIGHPTE=y CONFIG_HW_PERF_EVENTS=y CONFIG_UACCESS_WITH_MEMCPY=y +# CONFIG_GENERIC_CPUFREQ_CPU0 is not set # Generic ARM Errata CONFIG_ARM_ERRATA_720789=y @@ -42,6 +44,7 @@ CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 CONFIG_LOCAL_TIMERS=y +CONFIG_ATAGS=y CONFIG_ATAGS_PROC=y CONFIG_PL330_DMA=y @@ -63,9 +66,6 @@ CONFIG_CPU_IDLE=y # CONFIG_CPU_IDLE_GOV_LADDER is not set CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 -CONFIG_LSM_MMAP_MIN_ADDR=32768 - CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -75,6 +75,16 @@ CONFIG_SUSPEND=y CONFIG_ARM_CPU_SUSPEND=y CONFIG_ARM_CPU_TOPOLOGY=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +CONFIG_LSM_MMAP_MIN_ADDR=32768 + +# CONFIG_XEN is not set + +CONFIG_PINCTRL=y +CONFIG_PINCONF=y + +CONFIG_COMMON_CLK=y + CONFIG_THERMAL=y CONFIG_ETHERNET=y @@ -84,20 +94,17 @@ CONFIG_PERF_COUNTERS=y CONFIG_CC_STACKPROTECTOR=y -CONFIG_AUTO_ZRELADDR=y - CONFIG_SECCOMP=y CONFIG_STRICT_DEVMEM=y CONFIG_SPARSE_IRQ=y # Generic HW for all ARM platforms -CONFIG_LEDS=y -CONFIG_LEDS_CPU=y CONFIG_LEDS_GPIO=m CONFIG_LBDAF=y +CONFIG_GPIOLIB=y CONFIG_RFKILL_GPIO=m CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIO_GENERIC_PLATFORM=m @@ -135,10 +142,13 @@ CONFIG_MMC_SPI=m CONFIG_MMC_DW=m CONFIG_MMC_DW_PLTFM=m CONFIG_MMC_DW_PCI=m +# CONFIG_MMC_DW_EXYNOS is not set # CONFIG_MMC_DW_IDMAC is not set CONFIG_MMC_SDHCI_PXAV3=m CONFIG_MMC_SDHCI_PXAV2=m +# CONFIG_DW_DMAC_BIG_ENDIAN_IO is not set + # Generic GPIO options CONFIG_GENERIC_GPIO=y @@ -233,12 +243,15 @@ CONFIG_UBIFS_FS_ZLIB=y # CONFIG_UBIFS_FS_DEBUG is not set # HW crypto and rng +CONFIG_CRYPTO_SHA1_ARM=m +CONFIG_CRYPTO_AES_ARM=m CONFIG_HW_RANDOM_ATMEL=m CONFIG_HW_RANDOM_EXYNOS=m # Device tree CONFIG_OF=y CONFIG_USE_OF=y +CONFIG_OF_IRQ=y CONFIG_ARM_ATAG_DTB_COMPAT=y CONFIG_ARM_APPENDED_DTB=y CONFIG_PROC_DEVICETREE=y @@ -251,6 +264,7 @@ CONFIG_OF_PCI_IRQ=y CONFIG_I2C_MUX_PINCTRL=m CONFIG_OF_MDIO=m CONFIG_MDIO_BUS_MUX_GPIO=m +CONFIG_MDIO_BUS_MUX_MMIOREG=m CONFIG_BPF_JIT=y @@ -262,6 +276,7 @@ CONFIG_EDAC_LEGACY_SYSFS=y CONFIG_RTC_DRV_88PM80X=m CONFIG_RTC_DRV_PL030=m CONFIG_RTC_DRV_PL031=m +CONFIG_RTC_DRV_SNVS=m CONFIG_RFKILL_REGULATOR=m CONFIG_INPUT_88PM80X_ONKEY=y CONFIG_INPUT_GP2A=m @@ -271,14 +286,22 @@ CONFIG_SERIAL_AMBA_PL010=m CONFIG_SERIAL_AMBA_PL011=m CONFIG_GPIO_PL061=y CONFIG_GPIO_MCP23S08=m +CONFIG_GPIO_ADNP=m CONFIG_PL310_ERRATA_753970=y CONFIG_MFD_88PM800=m CONFIG_MFD_88PM805=m +CONFIG_MFD_SYSCON=y +# CONFIG_MFD_SMSC is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_MAX8907 is not set + CONFIG_REGULATOR_VIRTUAL_CONSUMER=m CONFIG_REGULATOR_USERSPACE_CONSUMER=m CONFIG_REGULATOR_GPIO=m CONFIG_REGULATOR_AD5398=m +CONFIG_REGULATOR_ANATOP=m +CONFIG_REGULATOR_FAN53555=m CONFIG_REGULATOR_ISL6271A=m CONFIG_REGULATOR_MAX1586=m CONFIG_REGULATOR_MAX8649=m @@ -291,6 +314,12 @@ CONFIG_REGULATOR_TPS6507X=m CONFIG_CHARGER_MANAGER=y CONFIG_EXTCON_GPIO=m +# CONFIG_ARM_VIRT_EXT is not set +# CONFIG_PINCTRL_EXYNOS4 is not set + +# CONFIG_AUTO_ZRELADDR is not set +# CONFIG_ASYMMETRIC_KEY_TYPE is not set + # CONFIG_VFIO is not set # CONFIG_XIP_KERNEL is not set @@ -355,3 +384,4 @@ CONFIG_EXTCON_GPIO=m # CONFIG_NET_VENDOR_CIRRUS is not set # CONFIG_CS89x0 is not set +# CONFIG_DVB_USB_PCTV452E is not set diff --git a/config-arm-highbank b/config-arm-highbank index 952a21a..ca27f65 100644 --- a/config-arm-highbank +++ b/config-arm-highbank @@ -59,4 +59,7 @@ CONFIG_OC_ETM=y # CONFIG_MEDIA_SUPPORT is not set # CONFIG_DRM is not set # CONFIG_SND is not set +# CONFIG_ARCH_MULTI_V4 is not set +# CONFIG_ARCH_MULTI_V4T is not set +# CONFIG_ARCH_MULTI_V6 is not set # end of list of requested disabled options diff --git a/config-arm-imx b/config-arm-imx index bddff88..8ffd965 100644 --- a/config-arm-imx +++ b/config-arm-imx @@ -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 diff --git a/config-arm-kirkwood b/config-arm-kirkwood index c8d0ec1..ff1dad7 100644 --- a/config-arm-kirkwood +++ b/config-arm-kirkwood @@ -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 diff --git a/config-arm-omap b/config-arm-omap index 5fb1bd6..68421b0 100644 --- a/config-arm-omap +++ b/config-arm-omap @@ -153,7 +153,6 @@ CONFIG_WL_TI=y CONFIG_WLCORE_SDIO=m CONFIG_TI_ST=m # CONFIG_TI_CPSW is not set -CONFIG_GPIOLIB=y CONFIG_MTD_NAND_OMAP2=y CONFIG_MTD_NAND_OMAP_PREFETCH=y CONFIG_MTD_NAND_OMAP_PREFETCH_DMA=y @@ -177,6 +176,7 @@ CONFIG_TWL4030_POWER=y CONFIG_TWL4030_CODEC=y CONFIG_TWL4030_WATCHDOG=m CONFIG_GPIO_TWL4030=m +CONFIG_GPIO_TWL6040=m CONFIG_CHARGER_TWL4030=m CONFIG_TWL6030_PWM=m CONFIG_TWL6040_CORE=y @@ -186,19 +186,23 @@ CONFIG_TI_DAVINCI_MDIO=m CONFIG_TI_DAVINCI_CPDMA=m CONFIG_LEDS_PWM=m +CONFIG_LEDS_LP8788=m CONFIG_MTD_ONENAND_OMAP2=y CONFIG_HDQ_MASTER_OMAP=m -CONFIG_I2C_OMAP=y +CONFIG_I2C_OMAP=m CONFIG_SPI_OMAP24XX=y CONFIG_MFD_OMAP_USB_HOST=y CONFIG_MFD_WL1273_CORE=m +CONFIG_MFD_LP8788=y CONFIG_REGULATOR_TWL4030=y +CONFIG_REGULATOR_LP8788=y # Enable V4L2 drivers for OMAP2+ CONFIG_MEDIA_CONTROLLER=y CONFIG_VIDEO_V4L2_SUBDEV_API=y CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_VIDEO_VPFE_CAPTURE=m CONFIG_VIDEO_OMAP2_VOUT=m +CONFIG_VIDEO_DM6446_CCDC=m # CONFIG_VIDEO_OMAP3 is not set # Also enable vivi driver - useful for testing a full kernelspace V4L2 driver CONFIG_V4L_TEST_DRIVERS=y @@ -227,11 +231,10 @@ CONFIG_OMAP2_DSS_DSI=y CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0 CONFIG_OMAP2_DSS_SLEEP_BEFORE_RESET=y CONFIG_OMAP2_DSS_SLEEP_AFTER_VENC_RESET=y -CONFIG_VIDEO_DM6446_CCDC=m CONFIG_PANEL_TFP410=m -CONFIG_PANEL_PICODLP=m CONFIG_PANEL_TAAL=m +CONFIG_PANEL_PICODLP=m CONFIG_BACKLIGHT_PANDORA=m # @@ -243,21 +246,22 @@ CONFIG_PANEL_NEC_NL8048HL11_01B=y CONFIG_PANEL_TPO_TD043MTEA1=y CONFIG_SND_OMAP_SOC=y -CONFIG_SND_OMAP_SOC_MCBSP=y -CONFIG_SND_OMAP_SOC_MCPDM=y -CONFIG_SND_OMAP_SOC_OVERO=y -CONFIG_SND_OMAP_SOC_OMAP3EVM=y -CONFIG_SND_OMAP_SOC_AM3517EVM=y -CONFIG_SND_OMAP_SOC_SDP3430=y -CONFIG_SND_OMAP_SOC_SDP4430=y -CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=y -CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE=y -CONFIG_SND_OMAP_SOC_ZOOM2=y +CONFIG_SND_OMAP_SOC_MCBSP=m +CONFIG_SND_OMAP_SOC_MCPDM=m +CONFIG_SND_OMAP_SOC_OVERO=m +CONFIG_SND_OMAP_SOC_OMAP3EVM=m +CONFIG_SND_OMAP_SOC_AM3517EVM=m +CONFIG_SND_OMAP_SOC_SDP3430=m +CONFIG_SND_OMAP_SOC_SDP4430=m +CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m +CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE=m +CONFIG_SND_OMAP_SOC_ZOOM2=m CONFIG_SND_OMAP_SOC_IGEP0020=y CONFIG_SND_OMAP_SOC_OMAP_HDMI=y # Because alsa is modular http://www.spinics.net/lists/linux-omap/msg67307.html # CONFIG_SND_OMAP_SOC_OMAP4_HDMI is not set CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040=m +CONFIG_SND_OMAP_SOC_OMAP_TWL4030=m CONFIG_SND_SOC_I2C_AND_SPI=y # CONFIG_SND_OMAP_SOC_RX51 is not set # CONFIG_SND_SOC_ALL_CODECS is not set @@ -295,19 +299,21 @@ CONFIG_TWL4030_USB=y CONFIG_TWL6030_USB=y CONFIG_RTC_DRV_TWL4030=y -CONFIG_TIDSPBRIDGE=m -CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE=0x600000 +CONFIG_IR_RX51=m + +# CONFIG_TIDSPBRIDGE is not set +# CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE=0x600000 # CONFIG_TIDSPBRIDGE_DEBUG is not set -CONFIG_TIDSPBRIDGE_RECOVERY=y +# CONFIG_TIDSPBRIDGE_RECOVERY=y # CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK is not set -CONFIG_TIDSPBRIDGE_WDT3=y -CONFIG_TIDSPBRIDGE_WDT_TIMEOUT=5 +# CONFIG_TIDSPBRIDGE_WDT3=y +# CONFIG_TIDSPBRIDGE_WDT_TIMEOUT=5 # CONFIG_TIDSPBRIDGE_NTFY_PWRERR is not set # CONFIG_TIDSPBRIDGE_BACKTRACE is not set -CONFIG_OMAP_REMOTEPROC=m -CONFIG_OMAP_BANDGAP=m -CONFIG_OMAP_IOVMM=m +# CONFIG_OMAP_REMOTEPROC is not set +# CONFIG_OMAP_BANDGAP is not set +# CONFIG_OMAP_IOVMM is not set CONFIG_CRYPTO_DEV_OMAP_SHAM=m CONFIG_CRYPTO_DEV_OMAP_AES=m diff --git a/config-arm-tegra b/config-arm-tegra index 748edc5..894b5db 100644 --- a/config-arm-tegra +++ b/config-arm-tegra @@ -18,13 +18,12 @@ CONFIG_MACH_WARIO=y CONFIG_MACH_VENTANA=y CONFIG_TEGRA_DEBUG_UARTD=y -CONFIG_NR_CPUS=4 CONFIG_ARM_CPU_TOPOLOGY=y CONFIG_TEGRA_IOMMU_GART=y CONFIG_TEGRA_IOMMU_SMMU=y -CONFIG_I2C_TEGRA=y +CONFIG_I2C_TEGRA=m # This block is temporary until we work out why the MMC modules don't work as modules CONFIG_MMC=y diff --git a/config-arm-versatile b/config-arm-versatile index 9c37936..758a78c 100644 --- a/config-arm-versatile +++ b/config-arm-versatile @@ -93,3 +93,10 @@ CONFIG_PATA_PLATFORM=m CONFIG_PATA_OF_PLATFORM=m # CONFIG_NET_VENDOR_BROADCOM is not set +# unset on versatille for jon masters +# CONFIG_GPIOLIB is not set +# CONFIG_ARCH_MULTI_V4 is not set +# CONFIG_ARCH_MULTI_V4T is not set +# CONFIG_ARCH_MULTI_V6 is not set +# CONFIG_DRM_EXYNOS is not set + diff --git a/config-generic b/config-generic index 86ddbe0..88f6ff1 100644 --- a/config-generic +++ b/config-generic @@ -191,49 +191,76 @@ CONFIG_EXTRA_FIRMWARE="" # CONFIG_MTD=m # CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# # CONFIG_MTD_CHAR is not set CONFIG_MTD_BLKDEVS=m CONFIG_MTD_BLOCK=m # CONFIG_MTD_BLOCK_RO is not set -# CONFIG_MTD_REDBOOT_PARTS is not set # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set # CONFIG_MTD_OOPS is not set # CONFIG_MTD_SWAP is not set + +# +# RAM/ROM/Flash chip drivers +# # CONFIG_MTD_CFI is not set # CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# # CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_TS5500 is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# Self-contained MTD device drivers +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +CONFIG_MTD_PHRAM=m # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# # CONFIG_MTD_DOCG3 is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set # CONFIG_MTD_NAND_VERIFY_WRITE is not set # CONFIG_MTD_NAND_ECC_BCH is not set # CONFIG_MTD_NAND_MUSEUM_IDS is not set # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_LPDDR is not set -# CONFIG_SM_FTL is not set -# CONFIG_MTD_TS5500 is not set -# CONFIG_MTD_INTEL_VR_NOR is not set -# CONFIG_MTD_PLATRAM is not set -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_AR7_PARTS is not set -# CONFIG_MTD_SLRAM is not set -CONFIG_MTD_PHRAM=m -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_ONENAND is not set -# CONFIG_MTD_UBI=m CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MTD_UBI_BEB_RESERVE=2 +CONFIG_MTD_UBI_BEB_LIMIT=20 +# CONFIG_MTD_UBI_FASTMAP is not set CONFIG_MTD_UBI_GLUEBI=m - # # Parallel port support # @@ -452,6 +479,7 @@ CONFIG_ATA_BMDMA=y CONFIG_ATA_VERBOSE_ERROR=y CONFIG_ATA_SFF=y CONFIG_ATA_PIIX=y +# CONFIG_SATA_HIGHBANK is not set CONFIG_ATA_ACPI=y CONFIG_BLK_DEV_SX8=m CONFIG_PDC_ADMA=m @@ -472,7 +500,6 @@ CONFIG_SATA_ULI=m CONFIG_SATA_VIA=m CONFIG_SATA_VITESSE=m CONFIG_SATA_ACARD_AHCI=m -# CONFIG_SATA_HIGHBANK is not set # CONFIG_PATA_LEGACY is not set CONFIG_PATA_ACPI=m @@ -623,6 +650,7 @@ CONFIG_TCP_MD5SIG=y # Networking options # CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set CONFIG_UNIX=y CONFIG_UNIX_DIAG=m CONFIG_NET_KEY=m @@ -702,6 +730,7 @@ CONFIG_IPV6_MIP6=y CONFIG_IPV6_SIT=m CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_TUNNEL=m +# CONFIG_IPV6_GRE is not set CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_MROUTE=y @@ -845,7 +874,6 @@ CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_TARGET_CLUSTERIP=m -CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_ECN=m @@ -853,6 +881,8 @@ CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m CONFIG_IP_NF_TARGET_REJECT=y CONFIG_IP_NF_TARGET_TTL=m +CONFIG_NF_NAT_IPV4=m +CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m @@ -884,6 +914,9 @@ CONFIG_IP6_NF_SECURITY=m CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_TARGET_HL=m +CONFIG_NF_NAT_IPV6=m +# CONFIG_IP6_NF_TARGET_MASQUERADE is not set +# CONFIG_IP6_NF_TARGET_NPT is not set # # Bridge: Netfilter Configuration @@ -1073,6 +1106,7 @@ CONFIG_DUMMY=m CONFIG_BONDING=m CONFIG_MACVLAN=m CONFIG_MACVTAP=m +CONFIG_VXLAN=m CONFIG_EQUALIZER=m CONFIG_TUN=m CONFIG_VETH=m @@ -1325,6 +1359,7 @@ CONFIG_NET_VENDOR_XIRCOM=y CONFIG_PCMCIA_XIRC2PS=m CONFIG_PHYLIB=y +CONFIG_AT803X_PHY=m CONFIG_AMD_PHY=m CONFIG_BROADCOM_PHY=m CONFIG_BCM87XX_PHY=m @@ -1380,6 +1415,7 @@ CONFIG_MLX4_EN_DCB=y CONFIG_SFC=m CONFIG_SFC_MCDI_MON=y CONFIG_SFC_SRIOV=y +CONFIG_SFC_PTP=y # CONFIG_SFC_MTD is not set @@ -1494,6 +1530,7 @@ CONFIG_BRCMFMAC=m CONFIG_BRCMFMAC_SDIO=y CONFIG_BRCMFMAC_SDIO_OOB=y CONFIG_BRCMFMAC_USB=y +# CONFIG_BRCMISCAN is not set # CONFIG_BRCMDBG is not set CONFIG_HERMES=m CONFIG_HERMES_CACHE_FW_ON_INIT=y @@ -2049,6 +2086,7 @@ CONFIG_TIFM_CORE=m CONFIG_TIFM_7XX1=m CONFIG_TCG_TPM=m CONFIG_TCG_TIS=m +# CONFIG_TCG_TIS_I2C_INFINEON is not set CONFIG_TCG_NSC=m CONFIG_TCG_ATMEL=m # CONFIG_TCG_INFINEON is not set @@ -2075,6 +2113,7 @@ CONFIG_CYCLADES=m # CONFIG_ISI is not set # CONFIG_RIO is not set CONFIG_SERIAL_JSM=m +# CONFIG_SERIAL_SCCNXP is not set # CONFIG_SERIAL_MFD_HSU is not set # CONFIG_SERIAL_ALTERA_JTAGUART is not set @@ -2083,6 +2122,7 @@ CONFIG_SERIAL_JSM=m # # Non-8250 serial port support # +# CONFIG_SERIAL_KGDB_NMI is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_XILINX_PS_UART is not set @@ -2171,6 +2211,7 @@ CONFIG_SENSORS_ADM1026=m CONFIG_SENSORS_ADM1029=m CONFIG_SENSORS_ADM1031=m CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7410=m CONFIG_SENSORS_ADS7828=m CONFIG_SENSORS_ADT7462=m CONFIG_SENSORS_ADT7470=m @@ -2290,6 +2331,7 @@ CONFIG_SENSORS_LTC2978=m CONFIG_SENSORS_MAX34440=m CONFIG_SENSORS_MAX8688=m CONFIG_SENSORS_MAX1668=m +CONFIG_SENSORS_MAX197=m # CONFIG_HMC6352 is not set # CONFIG_BMP085 is not set @@ -2304,6 +2346,7 @@ CONFIG_W1_CON=y CONFIG_W1_MASTER_DS2490=m CONFIG_W1_MASTER_DS2482=m CONFIG_W1_MASTER_DS1WM=m +# CONFIG_HDQ_MASTER_OMAP is not set CONFIG_W1_SLAVE_THERM=m CONFIG_W1_SLAVE_SMEM=m CONFIG_W1_SLAVE_DS2408=m @@ -2375,6 +2418,7 @@ CONFIG_W83697UG_WDT=m CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_TIMERIOMEM=m +CONFIG_HW_RANDOM_TPM=m # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_RTC_DEBUG is not set @@ -2408,6 +2452,7 @@ CONFIG_RTC_DRV_RS5C372=m # CONFIG_RTC_DRV_TEST is not set CONFIG_RTC_DRV_X1205=m CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_DS2404=m CONFIG_RTC_DRV_STK17TA8=m # CONFIG_RTC_DRV_S35390A is not set CONFIG_RTC_DRV_RX8581=m @@ -2450,7 +2495,7 @@ CONFIG_VGA_ARB_MAX_GPUS=16 CONFIG_DRM=m CONFIG_DRM_LOAD_EDID_FIRMWARE=y -# CONFIG_DRM_AST is not set # do not enable on f17 or older +# CONFIG_DRM_AST is not set # do not enable on f17 or older # CONFIG_DRM_CIRRUS_QEMU is not set # do not enable on f17 or older # CONFIG_DRM_TDFX is not set # CONFIG_DRM_R128 is not set @@ -2465,6 +2510,8 @@ CONFIG_DRM_I915=m CONFIG_DRM_I915_KMS=y CONFIG_DRM_VIA=m CONFIG_DRM_NOUVEAU=m +CONFIG_NOUVEAU_DEBUG=5 +CONFIG_NOUVEAU_DEBUG_DEFAULT=3 CONFIG_DRM_NOUVEAU_BACKLIGHT=y CONFIG_DRM_NOUVEAU_DEBUG=y # CONFIG_DRM_PSB is not set @@ -2488,6 +2535,8 @@ CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=8192 CONFIG_HANGCHECK_TIMER=m +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_MEDIA_PCI_SUPPORT=y # # Multimedia devices # @@ -2545,6 +2594,7 @@ CONFIG_VIDEO_CX231XX_RC=y CONFIG_VIDEO_HEXIUM_ORION=m CONFIG_VIDEO_HEXIUM_GEMINI=m CONFIG_VIDEO_IVTV=m +# CONFIG_VIDEO_IVTV_ALSA is not set CONFIG_VIDEO_MEYE=m CONFIG_VIDEO_MXB=m CONFIG_VIDEO_PVRUSB2_DVB=y @@ -2556,6 +2606,8 @@ CONFIG_VIDEO_SAA7134_ALSA=m CONFIG_VIDEO_SAA7134_DVB=m CONFIG_VIDEO_SAA7134_RC=y CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_STK1160=m +CONFIG_VIDEO_STK1160_AC97=y CONFIG_VIDEO_W9966=m CONFIG_VIDEO_ZORAN=m CONFIG_VIDEO_ZORAN_AVS6EYES=m @@ -2619,6 +2671,7 @@ CONFIG_DVB_BT8XX=m CONFIG_DVB_BUDGET_CORE=m CONFIG_DVB_PLUTO2=m CONFIG_SMS_SIANO_MDTV=m +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y CONFIG_SMS_USB_DRV=m CONFIG_SMS_SDIO_DRV=m CONFIG_DVB_TTUSB_DEC=m @@ -2636,6 +2689,7 @@ CONFIG_DVB_FIREDTV=m CONFIG_DVB_NGENE=m CONFIG_DVB_DDBRIDGE=m CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_USB_V2=m CONFIG_DVB_AV7110=m CONFIG_DVB_AV7110_OSD=y @@ -2648,7 +2702,10 @@ CONFIG_DVB_TTUSB_BUDGET=m CONFIG_DVB_USB_CINERGY_T2=m CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set + CONFIG_DVB_B2C2_FLEXCOP_PCI=m +# CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG is not set CONFIG_DVB_B2C2_FLEXCOP_USB=m # CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set CONFIG_DVB_USB=m @@ -2720,9 +2777,13 @@ CONFIG_IR_ENE=m CONFIG_IR_STREAMZAP=m CONFIG_IR_WINBOND_CIR=m CONFIG_IR_IGUANA=m +CONFIG_IR_TTUSBIR=m CONFIG_IR_GPIO_CIR=m CONFIG_V4L_MEM2MEM_DRIVERS=y +# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set +# CONFIG_V4L_TEST_DRIVERS is not set + # CONFIG_VIDEO_MEM2MEM_TESTDEV is not set # @@ -2789,7 +2850,7 @@ CONFIG_FB_I810_I2C=y # CONFIG_FB_SM501 is not set # CONFIG_FB_SMSCUFX is not set CONFIG_FB_TILEBLITTING=y -# CONFIG_FB_MODE_HELPERS is not set +CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TRIDENT is not set # CONFIG_FB_UVESA is not set CONFIG_FB_VESA=y @@ -3096,6 +3157,7 @@ CONFIG_HID_MULTITOUCH=m CONFIG_HID_NTRIG=y CONFIG_HID_QUANTA=y CONFIG_HID_PRIMAX=m +CONFIG_HID_PS3REMOTE=m CONFIG_HID_PRODIKEYS=m CONFIG_HID_DRAGONRISE=m CONFIG_HID_GYRATION=m @@ -3115,6 +3177,7 @@ CONFIG_HID_TOPSEED=m CONFIG_HID_THRUSTMASTER=m CONFIG_HID_ZEROPLUS=m CONFIG_HID_ZYDACRON=m +# CONFIG_HID_SENSOR_HUB is not set CONFIG_HID_EMS_FF=m CONFIG_HID_ELECOM=m CONFIG_HID_UCLOGIC=m @@ -3306,6 +3369,7 @@ CONFIG_USB_SERIAL_MCT_U232=m CONFIG_USB_SERIAL_MOS7720=m CONFIG_USB_SERIAL_MOS7715_PARPORT=y # CONFIG_USB_SERIAL_ZIO is not set +# CONFIG_USB_SERIAL_ZTE is not set CONFIG_USB_SERIAL_MOS7840=m CONFIG_USB_SERIAL_MOTOROLA=m CONFIG_USB_SERIAL_NAVMAN=m @@ -3346,6 +3410,7 @@ CONFIG_USB_ADUTUX=m CONFIG_USB_SEVSEG=m CONFIG_USB_ALI_M5632=y CONFIG_USB_APPLEDISPLAY=m +# CONFIG_OMAP_USB2 is not set CONFIG_USB_ATM=m CONFIG_USB_CXACRU=m # CONFIG_USB_C67X00_HCD is not set @@ -3364,6 +3429,7 @@ CONFIG_USB_FILE_STORAGE=m CONFIG_USB_IOWARRIOR=m CONFIG_USB_ISIGHTFW=m CONFIG_USB_YUREX=m +CONFIG_USB_EZUSB_FX2=m CONFIG_USB_LCD=m CONFIG_USB_LD=m CONFIG_USB_LEGOTOWER=m @@ -3614,6 +3680,7 @@ CONFIG_RPCSEC_GSS_KRB5=m CONFIG_CIFS=m CONFIG_CIFS_STATS=y # CONFIG_CIFS_STATS2 is not set +CONFIG_CIFS_SMB2=y CONFIG_CIFS_UPCALL=y CONFIG_CIFS_XATTR=y CONFIG_CIFS_POSIX=y @@ -3785,6 +3852,7 @@ CONFIG_DEBUG_NX_TEST=m CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_DEBUG_BOOT_PARAMS=y CONFIG_DEBUG_VM=y +# CONFIG_DEBUG_VM_RB is not set # revisit this if performance isn't horrible # CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set CONFIG_LOCKUP_DETECTOR=y # CONFIG_DEBUG_INFO_REDUCED is not set @@ -3948,6 +4016,8 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=m CONFIG_BACKLIGHT_PROGEAR=m # CONFIG_BACKLIGHT_ADP8860 is not set # CONFIG_BACKLIGHT_ADP8870 is not set +# CONFIG_BACKLIGHT_LM3630 is not set +# CONFIG_BACKLIGHT_LM3639 is not set CONFIG_FB_NVIDIA_BACKLIGHT=y CONFIG_FB_RIVA_BACKLIGHT=y CONFIG_FB_RADEON_BACKLIGHT=y @@ -3999,10 +4069,15 @@ CONFIG_KEXEC=y CONFIG_HWMON=y # CONFIG_HWMON_DEBUG_CHIP is not set CONFIG_THERMAL_HWMON=y +# CONFIG_CPU_THERMAL is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y +# +# Bus devices +# +# CONFIG_OMAP_OCP2SCP is not set CONFIG_CONNECTOR=y CONFIG_PROC_EVENTS=y @@ -4037,6 +4112,8 @@ CONFIG_NET_VENDOR_SMC=y # CONFIG_MOUSE_ATIXL is not set +# CONFIG_MEDIA_PARPORT_SUPPORT is not set + CONFIG_RADIO_ADAPTERS=y CONFIG_RADIO_TEA5764=m CONFIG_RADIO_SAA7706H=m @@ -4083,6 +4160,7 @@ CONFIG_LEDS_CLASS=y # CONFIG_LEDS_PCA9633 is not set CONFIG_LEDS_DELL_NETBOOKS=m # CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_LM355x is not set # CONFIG_LEDS_OT200 is not set CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=m @@ -4090,12 +4168,14 @@ CONFIG_LEDS_TRIGGER_ONESHOT=m CONFIG_LEDS_TRIGGER_IDE_DISK=y CONFIG_LEDS_TRIGGER_HEARTBEAT=m CONFIG_LEDS_TRIGGER_BACKLIGHT=m +# CONFIG_LEDS_TRIGGER_CPU is not set CONFIG_LEDS_TRIGGER_DEFAULT_ON=m CONFIG_LEDS_TRIGGER_TRANSIENT=m CONFIG_LEDS_ALIX2=m CONFIG_LEDS_CLEVO_MAIL=m CONFIG_LEDS_INTEL_SS4200=m CONFIG_LEDS_LM3530=m +# CONFIG_LEDS_LM3642 is not set CONFIG_LEDS_LM3556=m CONFIG_LEDS_BLINKM=m CONFIG_LEDS_LP3944=m @@ -4129,6 +4209,8 @@ CONFIG_FTRACE_MCOUNT_RECORD=y # CONFIG_TRACE_BRANCH_PROFILING is not set CONFIG_FUNCTION_PROFILER=y CONFIG_RING_BUFFER_BENCHMARK=m +# CONFIG_RBTREE_TEST is not set +# CONFIG_INTERVAL_TREE_TEST is not set CONFIG_FUNCTION_TRACER=y CONFIG_STACK_TRACER=y # CONFIG_FUNCTION_GRAPH_TRACER is not set @@ -4344,9 +4426,19 @@ CONFIG_ALTERA_STAPL=m # CONFIG_WIMAX_GDM72XX is not set # CONFIG_IPACK_BUS is not set # CONFIG_CSR_WIFI is not set -# +# CONFIG_ZCACHE2 is not set +# CONFIG_NET_VENDOR_SILICOM is not set +# CONFIG_SBYPASS is not set +# CONFIG_BPCTL is not set +# CONFIG_CED1401 is not set +# CONFIG_DGRP is not set # END OF STAGING +# +# Remoteproc drivers (EXPERIMENTAL) +# +# CONFIG_STE_MODEM_RPROC is not set + CONFIG_LIBFC=m CONFIG_LIBFCOE=m CONFIG_FCOE=m @@ -4490,3 +4582,4 @@ CONFIG_IOMMU_SUPPORT=y # CONFIG_CRYPTO_KEY_TYPE is not set # CONFIG_PGP_LIBRARY is not set # CONFIG_PGP_PRELOAD is not set +# CONFIG_ASYMMETRIC_KEY_TYPE is not set diff --git a/config-powerpc-generic b/config-powerpc-generic index a263acc..a6ef1c4 100644 --- a/config-powerpc-generic +++ b/config-powerpc-generic @@ -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 + diff --git a/config-powerpc64 b/config-powerpc64 index 82f4c60..7c0477c 100644 --- a/config-powerpc64 +++ b/config-powerpc64 @@ -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 diff --git a/config-s390x b/config-s390x index 451512e..41e41c5 100644 --- a/config-s390x +++ b/config-s390x @@ -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 diff --git a/config-sparc64-generic b/config-sparc64-generic index ebc891d..e15e2ef 100644 --- a/config-sparc64-generic +++ b/config-sparc64-generic @@ -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 + diff --git a/config-x86-32-generic b/config-x86-32-generic index b1a0499..1216d47 100644 --- a/config-x86-32-generic +++ b/config-x86-32-generic @@ -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 diff --git a/config-x86-generic b/config-x86-generic index f523222..ae1c37f 100644 --- a/config-x86-generic +++ b/config-x86-generic @@ -91,10 +91,11 @@ CONFIG_ACPI_APEI_MEMORY_FAILURE=y # CONFIG_ACPI_APEI_EINJ is not set CONFIG_ACPI_IPMI=m CONFIG_ACPI_CUSTOM_METHOD=m -CONFIG_ACPI_BGRT=m +CONFIG_ACPI_BGRT=y CONFIG_X86_ACPI_CPUFREQ=y CONFIG_X86_PCC_CPUFREQ=y +CONFIG_X86_ACPI_CPUFREQ_CPB=y CONFIG_X86_POWERNOW_K8=y CONFIG_X86_P4_CLOCKMOD=y # CONFIG_X86_SPEEDSTEP_CENTRINO is not set @@ -424,3 +425,5 @@ CONFIG_INTEL_MEI=m # Maybe enable in debug kernels? # CONFIG_DEBUG_NMI_SELFTEST is not set + + diff --git a/config-x86_64-generic b/config-x86_64-generic index 342b862..6003f11 100644 --- a/config-x86_64-generic +++ b/config-x86_64-generic @@ -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 diff --git a/don-t-do-blind-d_drop-in-nfs_prime_dcache.patch b/don-t-do-blind-d_drop-in-nfs_prime_dcache.patch deleted file mode 100644 index d4e837a..0000000 --- a/don-t-do-blind-d_drop-in-nfs_prime_dcache.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 696199f8ccf7fc6d17ef89c296ad3b6c78c52d9c Mon Sep 17 00:00:00 2001 -From: Al Viro -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 ---- - 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 - diff --git a/ext4-set-bg_itable_unused-when-resizing.patch b/ext4-set-bg_itable_unused-when-resizing.patch deleted file mode 100644 index bd7bc44..0000000 --- a/ext4-set-bg_itable_unused-when-resizing.patch +++ /dev/null @@ -1,26 +0,0 @@ -commit 93f9052643409c13b3b5f76833865087351f55b8 -Author: Theodore Ts'o -Date: Wed Sep 12 14:32:42 2012 -0400 - - ext4: set bg_itable_unused when resizing - - Set bg_itable_unused for file systems that have uninit_bg enabled. - This will speed up the first e2fsck run after the file system is - resized. - - Signed-off-by: "Theodore Ts'o" - -diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c -index 7adc088..a5be589 100644 ---- a/fs/ext4/resize.c -+++ b/fs/ext4/resize.c -@@ -1268,6 +1268,9 @@ static int ext4_setup_new_descs(handle_t *handle, struct super_block *sb, - ext4_free_group_clusters_set(sb, gdp, - EXT4_B2C(sbi, group_data->free_blocks_count)); - ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb)); -+ if (ext4_has_group_desc_csum(sb)) -+ ext4_itable_unused_set(sb, gdp, -+ EXT4_INODES_PER_GROUP(sb)); - gdp->bg_flags = cpu_to_le16(*bg_flags); - ext4_group_desc_csum_set(sb, group, gdp); - diff --git a/fs-lock-splice_read-and-splice_write-functions.patch b/fs-lock-splice_read-and-splice_write-functions.patch deleted file mode 100644 index 938cbd9..0000000 --- a/fs-lock-splice_read-and-splice_write-functions.patch +++ /dev/null @@ -1,74 +0,0 @@ -Lock splice_read and splice_write functions - -commit 1a25b1c4ce189e3926f2981f3302352a930086db -Author: Mikulas Patocka -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 - Signed-off-by: Linus Torvalds - -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) diff --git a/kernel.spec b/kernel.spec index ebcf568..62f23e7 100644 --- a/kernel.spec +++ b/kernel.spec @@ -54,19 +54,19 @@ Summary: The Linux kernel # For non-released -rc kernels, this will be appended after the rcX and # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3" # -%global baserelease 8 +%global baserelease 101 %global fedora_build %{baserelease} # base_sublevel is the kernel version we're starting with and patching # on top of -- for example, 2.6.22-rc7-git1 starts with a 2.6.21 base, # which yields a base_sublevel of 21. -%define base_sublevel 6 +%define base_sublevel 7 ## If this is a released kernel ## %if 0%{?released_kernel} # Do we have a -stable update to apply? -%define stable_update 11 +%define stable_update 3 # Is it a -stable RC? %define stable_rc 0 # Set rpm version accordingly @@ -712,7 +712,6 @@ Patch19000: ips-noirq.patch # ARM Patch21000: arm-read_current_timer.patch Patch21001: arm-fix-omapdrm.patch -Patch21002: arm-fix_radio_shark.patch Patch21003: arm-alignment-faults.patch # OMAP @@ -722,7 +721,6 @@ Patch21005: arm-tegra-usb-no-reset-linux33.patch Patch21006: arm-tegra-sdhci-module-fix.patch # ARM highbank patches -Patch21010: arm-highbank-sata-fix.patch #rhbz 754518 Patch21235: scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch @@ -739,69 +737,20 @@ Patch22014: efifb-skip-DMI-checks-if-bootloader-knows.patch #rhbz 857324 Patch22070: net-tcp-bz857324.patch -#rhbz 869904 869909 CVE-2012-4508 -Patch22080: 0001-ext4-ext4_inode_info-diet.patch -Patch22081: 0002-ext4-give-i_aiodio_unwritten-a-more-appropriate-name.patch -Patch22082: 0003-ext4-fix-unwritten-counter-leakage.patch -Patch22083: 0004-ext4-completed_io-locking-cleanup.patch -Patch22084: 0005-ext4-serialize-dio-nonlocked-reads-with-defrag-worke.patch -Patch22085: 0006-ext4-serialize-unlocked-dio-reads-with-truncate.patch -Patch22086: 0007-ext4-endless-truncate-due-to-nonlocked-dio-readers.patch -Patch22087: 0008-ext4-serialize-truncate-with-owerwrite-DIO-workers.patch -Patch22088: 0009-ext4-punch_hole-should-wait-for-DIO-writers.patch -Patch22089: 0010-ext4-fix-ext_remove_space-for-punch_hole-case.patch -Patch22090: 0011-ext4-fix-ext4_flush_completed_IO-wait-semantics.patch -Patch22091: 0012-ext4-serialize-fallocate-with-ext4_convert_unwritten.patch - -Patch22100: uprobes-upstream-backport.patch - #rhbz 871078 Patch22112: USB-report-submission-of-active-URBs.patch -#rhbz 869341 -Patch22113: smp_irq_move_cleanup_interrupt.patch - -#rhbz 812129 -Patch22120: block-fix-a-crash-when-block-device-is.patch -Patch22121: blockdev-turn-a-rw-semaphore-into-a-percpu-rw-sem.patch -Patch22122: fs-lock-splice_read-and-splice_write-functions.patch - -#rhbz 874791 -Patch22125: Bluetooth-Add-support-for-BCM20702A0.patch - #rhbz CVE-2012-4530 868285 880147 -Patch21228: exec-do-not-leave-bprm-interp-on-stack.patch Patch21229: exec-use-eloop-for-max-recursion-depth.patch -#rhbz 869629 -Patch21230: SCSI-mvsas-Fix-oops-when-ata-commond-timeout.patch - #rhbz 851278 Patch21231: 8139cp-revert-set-ring-address-before-enabling-receiver.patch Patch21232: 8139cp-set-ring-address-after-enabling-C-mode.patch Patch21233: 8139cp-re-enable-interrupts-after-tx-timeout.patch -#rhbz 883414 -Patch21234: mac80211-fix-ibss-scanning.patch - -#rhbz 873107 -Patch21237: 0001-ACPI-sony-laptop-do-proper-memcpy-for-ACPI_TYPE_INTE.patch - -#rhbz 874372 -Patch21238: don-t-do-blind-d_drop-in-nfs_prime_dcache.patch - -#rhbz 853064 -Patch21239: aoe-remove-extra-bdi_init.patch - -#rhbz 890547 -Patch21240: ACPI-do-not-use-Lid-and-Sleep-button-for-S5-wakeup.patch - #rhbz 886946 Patch21241: iwlegacy-fix-IBSS-cleanup.patch -#rhbz 852833 -Patch21245: ext4-set-bg_itable_unused-when-resizing.patch - #rhbz 896051 896038 CVE-2013-0190 Patch21250: xen-fix-stack-corruption-in-xen_failsafe_callback.patch @@ -1369,13 +1318,11 @@ ApplyPatch vmbugon-warnon.patch # # ARM # -ApplyPatch arm-read_current_timer.patch -ApplyPatch arm-fix-omapdrm.patch -ApplyPatch arm-fix_radio_shark.patch +#ApplyPatch arm-read_current_timer.patch +#ApplyPatch arm-fix-omapdrm.patch ApplyPatch arm-tegra-nvec-kconfig.patch ApplyPatch arm-tegra-usb-no-reset-linux33.patch ApplyPatch arm-tegra-sdhci-module-fix.patch -ApplyPatch arm-highbank-sata-fix.patch ApplyPatch arm-alignment-faults.patch # @@ -1450,7 +1397,7 @@ ApplyPatch linux-2.6-e1000-ich9-montevina.patch # DRM core #ApplyPatch drm-edid-try-harder-to-fix-up-broken-headers.patch -ApplyPatch drm-vgem.patch +#ApplyPatch drm-vgem.patch # Nouveau DRM @@ -1493,74 +1440,25 @@ ApplyPatch weird-root-dentry-name-debug.patch #selinux ptrace child permissions ApplyPatch selinux-apply-different-permission-to-ptrace-child.patch -ApplyPatch efifb-skip-DMI-checks-if-bootloader-knows.patch +# ApplyPatch efifb-skip-DMI-checks-if-bootloader-knows.patch #rhbz 857324 ApplyPatch net-tcp-bz857324.patch -#rhbz 869904 869909 CVE-2012-4508 -ApplyPatch 0001-ext4-ext4_inode_info-diet.patch -ApplyPatch 0002-ext4-give-i_aiodio_unwritten-a-more-appropriate-name.patch -ApplyPatch 0003-ext4-fix-unwritten-counter-leakage.patch -ApplyPatch 0004-ext4-completed_io-locking-cleanup.patch -ApplyPatch 0005-ext4-serialize-dio-nonlocked-reads-with-defrag-worke.patch -ApplyPatch 0006-ext4-serialize-unlocked-dio-reads-with-truncate.patch -ApplyPatch 0007-ext4-endless-truncate-due-to-nonlocked-dio-readers.patch -ApplyPatch 0008-ext4-serialize-truncate-with-owerwrite-DIO-workers.patch -ApplyPatch 0009-ext4-punch_hole-should-wait-for-DIO-writers.patch -ApplyPatch 0010-ext4-fix-ext_remove_space-for-punch_hole-case.patch -ApplyPatch 0011-ext4-fix-ext4_flush_completed_IO-wait-semantics.patch -ApplyPatch 0012-ext4-serialize-fallocate-with-ext4_convert_unwritten.patch - -ApplyPatch uprobes-upstream-backport.patch - #rhbz 871078 ApplyPatch USB-report-submission-of-active-URBs.patch -#rhbz 869341 -ApplyPatch smp_irq_move_cleanup_interrupt.patch - -#rhbz 812129 -ApplyPatch block-fix-a-crash-when-block-device-is.patch -ApplyPatch blockdev-turn-a-rw-semaphore-into-a-percpu-rw-sem.patch -ApplyPatch fs-lock-splice_read-and-splice_write-functions.patch - -#rhbz 874791 -ApplyPatch Bluetooth-Add-support-for-BCM20702A0.patch - #rhbz CVE-2012-4530 868285 880147 -ApplyPatch exec-do-not-leave-bprm-interp-on-stack.patch ApplyPatch exec-use-eloop-for-max-recursion-depth.patch -#rhbz 869629 -ApplyPatch SCSI-mvsas-Fix-oops-when-ata-commond-timeout.patch - #rhbz 851278 ApplyPatch 8139cp-revert-set-ring-address-before-enabling-receiver.patch -R ApplyPatch 8139cp-set-ring-address-after-enabling-C-mode.patch ApplyPatch 8139cp-re-enable-interrupts-after-tx-timeout.patch -#rhbz 883414 -ApplyPatch mac80211-fix-ibss-scanning.patch - -#rhbz 873107 -ApplyPatch 0001-ACPI-sony-laptop-do-proper-memcpy-for-ACPI_TYPE_INTE.patch - -#rhbz 874372 -ApplyPatch don-t-do-blind-d_drop-in-nfs_prime_dcache.patch - -#rhbz 853064 -ApplyPatch aoe-remove-extra-bdi_init.patch - -#rhbz 890547 -ApplyPatch ACPI-do-not-use-Lid-and-Sleep-button-for-S5-wakeup.patch - #rhbz 886946 ApplyPatch iwlegacy-fix-IBSS-cleanup.patch -#rhbz 852833 -ApplyPatch ext4-set-bg_itable_unused-when-resizing.patch - #rhbz 896051 896038 CVE-2013-0190 ApplyPatch xen-fix-stack-corruption-in-xen_failsafe_callback.patch @@ -1788,8 +1686,8 @@ BuildKernel() { # Make sure the Makefile and version.h have a matching timestamp so that # external modules can be built - touch -r $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/Makefile $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/include/linux/version.h - touch -r $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/.config $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/include/linux/autoconf.h + touch -r $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/Makefile $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/include/generated/uapi/linux/version.h + # Copy .config to include/config/auto.conf so "make prepare" is unnecessary. cp $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/.config $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/include/config/auto.conf @@ -2298,6 +2196,7 @@ fi %dir %{_libexecdir}/perf-core %{_libexecdir}/perf-core/* %{_mandir}/man[1-8]/perf* +%{_sysconfdir}/bash_completion.d/perf %doc linux-%{KVERREL}/tools/perf/Documentation/examples.txt %files -n python-perf @@ -2427,6 +2326,9 @@ fi # '-' | | # '-' %changelog +* Fri Jan 18 2013 Josh Boyer - 3.7.3-101 +- Linux v3.7.3 + * Wed Jan 16 2013 Justin M. Forbes - 3.6.11-8 - Fix for CVE-2013-0190 xen corruption with 32bit pvops (rhbz 896051 896038) - Fix resize2fs issue with ext4 (rhbz 852833) diff --git a/linux-2.6-serial-460800.patch b/linux-2.6-serial-460800.patch index 979b248..0e68378 100644 --- a/linux-2.6-serial-460800.patch +++ b/linux-2.6-serial-460800.patch @@ -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. diff --git a/lis3-improve-handling-of-null-rate.patch b/lis3-improve-handling-of-null-rate.patch index 9851256..30ed26d 100644 --- a/lis3-improve-handling-of-null-rate.patch +++ b/lis3-improve-handling-of-null-rate.patch @@ -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)]; } diff --git a/mac80211-fix-ibss-scanning.patch b/mac80211-fix-ibss-scanning.patch deleted file mode 100644 index c2bc698..0000000 --- a/mac80211-fix-ibss-scanning.patch +++ /dev/null @@ -1,132 +0,0 @@ -Do not scan on no-IBSS and disabled channels in IBSS mode. Doing this -can trigger Microcode errors on iwlwifi and iwlegacy drivers. - -Also rename ieee80211_request_internal_scan() function since it is only -used in IBSS mode and simplify calling it from ieee80211_sta_find_ibss(). - -This patch should address: -https://bugzilla.redhat.com/show_bug.cgi?id=883414 -https://bugzilla.kernel.org/show_bug.cgi?id=49411 - -Reported-by: Jesse Kahtava -Reported-by: Mikko Rapeli -Cc: stable@vger.kernel.org -Signed-off-by: Stanislaw Gruszka ---- - net/mac80211/ibss.c | 9 ++++----- - net/mac80211/ieee80211_i.h | 6 +++--- - net/mac80211/scan.c | 34 ++++++++++++++++++++++++---------- - 3 files changed, 31 insertions(+), 18 deletions(-) - -diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c -index c21e33d..d9df6b8 100644 ---- a/net/mac80211/ibss.c -+++ b/net/mac80211/ibss.c -@@ -678,8 +678,8 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) - sdata_info(sdata, - "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n"); - -- ieee80211_request_internal_scan(sdata, -- ifibss->ssid, ifibss->ssid_len, NULL); -+ ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len, -+ NULL); - } - - static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) -@@ -777,9 +777,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) - IEEE80211_SCAN_INTERVAL)) { - sdata_info(sdata, "Trigger new scan to find an IBSS to join\n"); - -- ieee80211_request_internal_scan(sdata, -- ifibss->ssid, ifibss->ssid_len, -- ifibss->fixed_channel ? ifibss->channel : NULL); -+ ieee80211_request_ibss_scan(sdata, ifibss->ssid, -+ ifibss->ssid_len, chan); - } else { - int interval = IEEE80211_SCAN_INTERVAL; - -diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h -index 156e583..bc48d4d 100644 ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -1247,9 +1247,9 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, - - /* scan/BSS handling */ - void ieee80211_scan_work(struct work_struct *work); --int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, -- const u8 *ssid, u8 ssid_len, -- struct ieee80211_channel *chan); -+int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, -+ const u8 *ssid, u8 ssid_len, -+ struct ieee80211_channel *chan); - int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, - struct cfg80211_scan_request *req); - void ieee80211_scan_cancel(struct ieee80211_local *local); -diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c -index 43e60b5..fab706f 100644 ---- a/net/mac80211/scan.c -+++ b/net/mac80211/scan.c -@@ -819,9 +819,9 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, - return res; - } - --int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, -- const u8 *ssid, u8 ssid_len, -- struct ieee80211_channel *chan) -+int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, -+ const u8 *ssid, u8 ssid_len, -+ struct ieee80211_channel *chan) - { - struct ieee80211_local *local = sdata->local; - int ret = -EBUSY; -@@ -835,22 +835,36 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, - - /* fill internal scan request */ - if (!chan) { -- int i, nchan = 0; -+ int i, max_n; -+ int n_ch = 0; - - for (band = 0; band < IEEE80211_NUM_BANDS; band++) { - if (!local->hw.wiphy->bands[band]) - continue; -- for (i = 0; -- i < local->hw.wiphy->bands[band]->n_channels; -- i++) { -- local->int_scan_req->channels[nchan] = -+ -+ max_n = local->hw.wiphy->bands[band]->n_channels; -+ for (i = 0; i < max_n; i++) { -+ struct ieee80211_channel *tmp_ch = - &local->hw.wiphy->bands[band]->channels[i]; -- nchan++; -+ -+ if (tmp_ch->flags & (IEEE80211_CHAN_NO_IBSS | -+ IEEE80211_CHAN_DISABLED)) -+ continue; -+ -+ local->int_scan_req->channels[n_ch] = tmp_ch; -+ n_ch++; - } - } - -- local->int_scan_req->n_channels = nchan; -+ if (WARN_ON_ONCE(n_ch == 0)) -+ goto unlock; -+ -+ local->int_scan_req->n_channels = n_ch; - } else { -+ if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IBSS | -+ IEEE80211_CHAN_DISABLED))) -+ goto unlock; -+ - local->int_scan_req->channels[0] = chan; - local->int_scan_req->n_channels = 1; - } --- -1.7.1 - --- -To unsubscribe from this list: send the line "unsubscribe linux-wireless" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html \ No newline at end of file diff --git a/smp_irq_move_cleanup_interrupt.patch b/smp_irq_move_cleanup_interrupt.patch deleted file mode 100644 index c9b385a..0000000 --- a/smp_irq_move_cleanup_interrupt.patch +++ /dev/null @@ -1,50 +0,0 @@ -commit 94777fc51b3ad85ff9f705ddf7cdd0eb3bbad5a6 -Author: Dimitri Sivanich -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 - Cc: Suresh Siddha - Cc: Joerg Roedel - Cc: Yinghai Lu - Cc: Alexander Gordeev - Link: http://lkml.kernel.org/r/20121016125021.GA22935@sgi.com - Signed-off-by: Ingo Molnar - -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); - - /* diff --git a/sources b/sources index fdb1a31..df992bd 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -1a1760420eac802c541a20ab51a093d1 linux-3.6.tar.xz -bd4bba74093405887d521309a74c19e9 patch-3.6.11.xz +21223369d682bcf44bcdfe1521095983 linux-3.7.tar.xz +d4aa39ec9610e9fbd7bb4f5aff2c5db8 patch-3.7.3.xz diff --git a/uprobes-upstream-backport.patch b/uprobes-upstream-backport.patch deleted file mode 100644 index 9614e41..0000000 --- a/uprobes-upstream-backport.patch +++ /dev/null @@ -1,1376 +0,0 @@ -Hello, - -Test builds: - f18: http://koji.fedoraproject.org/koji/taskinfo?taskID=4635065 - f17: http://koji.fedoraproject.org/koji/taskinfo?taskID=4635062 - -The split-out series is available in the git repository at: - http://fedorapeople.org/cgit/aarapov/public_git/kernel-uprobes.git - -Just jistone's patch is not upstream that exports functions. -Yes, I know it must go to upstream. :-) I will try to do what I can before -the next uprobes update. - ---------------------------------------------------------------- -Josh Stone (1): - uprobes: add exports necessary for uprobes use by modules - -Oleg Nesterov (35): - uprobes: Kill uprobes_state->count - uprobes: Kill dup_mmap()->uprobe_mmap(), simplify uprobe_mmap/munmap - uprobes: Change uprobe_mmap() to ignore the errors but check fatal_signal_pending() - uprobes: Do not use -EEXIST in install_breakpoint() paths - uprobes: Introduce MMF_HAS_UPROBES - uprobes: Fold uprobe_reset_state() into uprobe_dup_mmap() - uprobes: Remove "verify" argument from set_orig_insn() - uprobes: uprobes_treelock should not disable irqs - uprobes: Introduce MMF_RECALC_UPROBES - uprobes: Teach find_active_uprobe() to clear MMF_HAS_UPROBES - ptrace/x86: Introduce set_task_blockstep() helper - ptrace/x86: Partly fix set_task_blockstep()->update_debugctlmsr() logic - uprobes/x86: Do not (ab)use TIF_SINGLESTEP/user_*_single_step() for single-stepping - uprobes/x86: Xol should send SIGTRAP if X86_EFLAGS_TF was set - uprobes/x86: Fix arch_uprobe_disable_step() && UTASK_SSTEP_TRAPPED interaction - uprobes: Make arch_uprobe_task->saved_trap_nr "unsigned int" - uprobes: Do not leak UTASK_BP_HIT if find_active_uprobe() fails - uprobes: Do not setup ->active_uprobe/state prematurely - uprobes: Fix UPROBE_SKIP_SSTEP checks in handle_swbp() - uprobes: Kill UTASK_BP_HIT state - uprobes: Move clear_thread_flag(TIF_UPROBE) to uprobe_notify_resume() - uprobes: Change write_opcode() to use FOLL_FORCE - uprobes: Change valid_vma() to demand VM_MAYEXEC rather than VM_EXEC - uprobes: Restrict valid_vma(false) to skip VM_SHARED vmas - uprobes: Kill set_swbp()->is_swbp_at_addr() - uprobes: Introduce copy_opcode(), kill read_opcode() - uprobes: Kill set_orig_insn()->is_swbp_at_addr() - uprobes: Simplify is_swbp_at_addr(), remove stale comments - uprobes/x86: Only rep+nop can be emulated correctly - uprobes: Don't return success if alloc_uprobe() fails - uprobes: Do not delete uprobe if uprobe_unregister() fails - uprobes: Fix handle_swbp() vs unregister() + register() race - uprobes: Introduce prepare_uprobe() - uprobes: Fix prepare_uprobe() race with itself - uprobes: Fix the racy uprobe->flags manipulation - -Sebastian Andrzej Siewior (4): - uprobes: Remove check for uprobe variable in handle_swbp() - uprobes: Don't put NULL pointer in uprobe_register() - uprobes: Introduce arch_uprobe_enable/disable_step() - uprobes/x86: Implement x86 specific arch_uprobe_*_step - -Srikar Dronamraju (1): - uprobes: Remove redundant lock_page/unlock_page - - arch/x86/include/asm/processor.h | 2 + - arch/x86/include/asm/uprobes.h | 3 +- - arch/x86/kernel/signal.c | 4 +- - arch/x86/kernel/step.c | 53 ++-- - arch/x86/kernel/uprobes.c | 64 ++++- - include/linux/sched.h | 3 + - include/linux/uprobes.h | 26 +- - kernel/events/uprobes.c | 564 ++++++++++++++++++--------------------- - kernel/fork.c | 6 +- - kernel/ptrace.c | 6 + - 10 files changed, 375 insertions(+), 356 deletions(-) - -diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h -index d048cad..433d2e5 100644 ---- a/arch/x86/include/asm/processor.h -+++ b/arch/x86/include/asm/processor.h -@@ -759,6 +759,8 @@ static inline void update_debugctlmsr(unsigned long debugctlmsr) - wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr); - } - -+extern void set_task_blockstep(struct task_struct *task, bool on); -+ - /* - * from system description table in BIOS. Mostly for MCA use, but - * others may find it useful: -diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h -index f3971bb..8ff8be7 100644 ---- a/arch/x86/include/asm/uprobes.h -+++ b/arch/x86/include/asm/uprobes.h -@@ -42,10 +42,11 @@ struct arch_uprobe { - }; - - struct arch_uprobe_task { -- unsigned long saved_trap_nr; - #ifdef CONFIG_X86_64 - unsigned long saved_scratch_register; - #endif -+ unsigned int saved_trap_nr; -+ unsigned int saved_tf; - }; - - extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr); -diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c -index b280908..0041e5a 100644 ---- a/arch/x86/kernel/signal.c -+++ b/arch/x86/kernel/signal.c -@@ -785,10 +785,8 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) - mce_notify_process(); - #endif /* CONFIG_X86_64 && CONFIG_X86_MCE */ - -- if (thread_info_flags & _TIF_UPROBE) { -- clear_thread_flag(TIF_UPROBE); -+ if (thread_info_flags & _TIF_UPROBE) - uprobe_notify_resume(regs); -- } - - /* deal with pending signal delivery */ - if (thread_info_flags & _TIF_SIGPENDING) -diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c -index c346d11..cd3b243 100644 ---- a/arch/x86/kernel/step.c -+++ b/arch/x86/kernel/step.c -@@ -157,6 +157,33 @@ static int enable_single_step(struct task_struct *child) - return 1; - } - -+void set_task_blockstep(struct task_struct *task, bool on) -+{ -+ unsigned long debugctl; -+ -+ /* -+ * Ensure irq/preemption can't change debugctl in between. -+ * Note also that both TIF_BLOCKSTEP and debugctl should -+ * be changed atomically wrt preemption. -+ * FIXME: this means that set/clear TIF_BLOCKSTEP is simply -+ * wrong if task != current, SIGKILL can wakeup the stopped -+ * tracee and set/clear can play with the running task, this -+ * can confuse the next __switch_to_xtra(). -+ */ -+ local_irq_disable(); -+ debugctl = get_debugctlmsr(); -+ if (on) { -+ debugctl |= DEBUGCTLMSR_BTF; -+ set_tsk_thread_flag(task, TIF_BLOCKSTEP); -+ } else { -+ debugctl &= ~DEBUGCTLMSR_BTF; -+ clear_tsk_thread_flag(task, TIF_BLOCKSTEP); -+ } -+ if (task == current) -+ update_debugctlmsr(debugctl); -+ local_irq_enable(); -+} -+ - /* - * Enable single or block step. - */ -@@ -169,19 +196,10 @@ static void enable_step(struct task_struct *child, bool block) - * So no one should try to use debugger block stepping in a program - * that uses user-mode single stepping itself. - */ -- if (enable_single_step(child) && block) { -- unsigned long debugctl = get_debugctlmsr(); -- -- debugctl |= DEBUGCTLMSR_BTF; -- update_debugctlmsr(debugctl); -- set_tsk_thread_flag(child, TIF_BLOCKSTEP); -- } else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) { -- unsigned long debugctl = get_debugctlmsr(); -- -- debugctl &= ~DEBUGCTLMSR_BTF; -- update_debugctlmsr(debugctl); -- clear_tsk_thread_flag(child, TIF_BLOCKSTEP); -- } -+ if (enable_single_step(child) && block) -+ set_task_blockstep(child, true); -+ else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) -+ set_task_blockstep(child, false); - } - - void user_enable_single_step(struct task_struct *child) -@@ -199,13 +217,8 @@ void user_disable_single_step(struct task_struct *child) - /* - * Make sure block stepping (BTF) is disabled. - */ -- if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) { -- unsigned long debugctl = get_debugctlmsr(); -- -- debugctl &= ~DEBUGCTLMSR_BTF; -- update_debugctlmsr(debugctl); -- clear_tsk_thread_flag(child, TIF_BLOCKSTEP); -- } -+ if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) -+ set_task_blockstep(child, false); - - /* Always clear TIF_SINGLESTEP... */ - clear_tsk_thread_flag(child, TIF_SINGLESTEP); -diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c -index 36fd420..aafa555 100644 ---- a/arch/x86/kernel/uprobes.c -+++ b/arch/x86/kernel/uprobes.c -@@ -41,6 +41,9 @@ - /* Adjust the return address of a call insn */ - #define UPROBE_FIX_CALL 0x2 - -+/* Instruction will modify TF, don't change it */ -+#define UPROBE_FIX_SETF 0x4 -+ - #define UPROBE_FIX_RIP_AX 0x8000 - #define UPROBE_FIX_RIP_CX 0x4000 - -@@ -239,6 +242,10 @@ static void prepare_fixups(struct arch_uprobe *auprobe, struct insn *insn) - insn_get_opcode(insn); /* should be a nop */ - - switch (OPCODE1(insn)) { -+ case 0x9d: -+ /* popf */ -+ auprobe->fixups |= UPROBE_FIX_SETF; -+ break; - case 0xc3: /* ret/lret */ - case 0xcb: - case 0xc2: -@@ -644,32 +651,63 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) - - /* - * Skip these instructions as per the currently known x86 ISA. -- * 0x66* { 0x90 | 0x0f 0x1f | 0x0f 0x19 | 0x87 0xc0 } -+ * rep=0x66*; nop=0x90 - */ --bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) -+static bool __skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) - { - int i; - - for (i = 0; i < MAX_UINSN_BYTES; i++) { -- if ((auprobe->insn[i] == 0x66)) -+ if (auprobe->insn[i] == 0x66) - continue; - - if (auprobe->insn[i] == 0x90) - return true; - -- if (i == (MAX_UINSN_BYTES - 1)) -- break; -+ break; -+ } -+ return false; -+} - -- if ((auprobe->insn[i] == 0x0f) && (auprobe->insn[i+1] == 0x1f)) -- return true; -+bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) -+{ -+ bool ret = __skip_sstep(auprobe, regs); -+ if (ret && (regs->flags & X86_EFLAGS_TF)) -+ send_sig(SIGTRAP, current, 0); -+ return ret; -+} - -- if ((auprobe->insn[i] == 0x0f) && (auprobe->insn[i+1] == 0x19)) -- return true; -+void arch_uprobe_enable_step(struct arch_uprobe *auprobe) -+{ -+ struct task_struct *task = current; -+ struct arch_uprobe_task *autask = &task->utask->autask; -+ struct pt_regs *regs = task_pt_regs(task); - -- if ((auprobe->insn[i] == 0x87) && (auprobe->insn[i+1] == 0xc0)) -- return true; -+ autask->saved_tf = !!(regs->flags & X86_EFLAGS_TF); - -- break; -+ regs->flags |= X86_EFLAGS_TF; -+ if (test_tsk_thread_flag(task, TIF_BLOCKSTEP)) -+ set_task_blockstep(task, false); -+} -+ -+void arch_uprobe_disable_step(struct arch_uprobe *auprobe) -+{ -+ struct task_struct *task = current; -+ struct arch_uprobe_task *autask = &task->utask->autask; -+ bool trapped = (task->utask->state == UTASK_SSTEP_TRAPPED); -+ struct pt_regs *regs = task_pt_regs(task); -+ /* -+ * The state of TIF_BLOCKSTEP was not saved so we can get an extra -+ * SIGTRAP if we do not clear TF. We need to examine the opcode to -+ * make it right. -+ */ -+ if (unlikely(trapped)) { -+ if (!autask->saved_tf) -+ regs->flags &= ~X86_EFLAGS_TF; -+ } else { -+ if (autask->saved_tf) -+ send_sig(SIGTRAP, task, 0); -+ else if (!(auprobe->fixups & UPROBE_FIX_SETF)) -+ regs->flags &= ~X86_EFLAGS_TF; - } -- return false; - } -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 23bddac..ba300be 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -446,6 +446,9 @@ extern int get_dumpable(struct mm_struct *mm); - #define MMF_VM_HUGEPAGE 17 /* set when VM_HUGEPAGE is set on vma */ - #define MMF_EXE_FILE_CHANGED 18 /* see prctl_set_mm_exe_file() */ - -+#define MMF_HAS_UPROBES 19 /* has uprobes */ -+#define MMF_RECALC_UPROBES 20 /* MMF_HAS_UPROBES can be wrong */ -+ - #define MMF_INIT_MASK (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK) - - struct sighand_struct { -diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h -index efe4b33..2459457 100644 ---- a/include/linux/uprobes.h -+++ b/include/linux/uprobes.h -@@ -35,16 +35,6 @@ struct inode; - # include - #endif - --/* flags that denote/change uprobes behaviour */ -- --/* Have a copy of original instruction */ --#define UPROBE_COPY_INSN 0x1 -- --/* Dont run handlers when first register/ last unregister in progress*/ --#define UPROBE_RUN_HANDLER 0x2 --/* Can skip singlestep */ --#define UPROBE_SKIP_SSTEP 0x4 -- - struct uprobe_consumer { - int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs); - /* -@@ -59,7 +49,6 @@ struct uprobe_consumer { - #ifdef CONFIG_UPROBES - enum uprobe_task_state { - UTASK_RUNNING, -- UTASK_BP_HIT, - UTASK_SSTEP, - UTASK_SSTEP_ACK, - UTASK_SSTEP_TRAPPED, -@@ -99,25 +88,27 @@ struct xol_area { - - struct uprobes_state { - struct xol_area *xol_area; -- atomic_t count; - }; -+ - extern int __weak set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); --extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr, bool verify); -+extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); - extern bool __weak is_swbp_insn(uprobe_opcode_t *insn); - extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); - extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); - extern int uprobe_mmap(struct vm_area_struct *vma); - extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end); -+extern void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm); - extern void uprobe_free_utask(struct task_struct *t); - extern void uprobe_copy_process(struct task_struct *t); - extern unsigned long __weak uprobe_get_swbp_addr(struct pt_regs *regs); -+extern void __weak arch_uprobe_enable_step(struct arch_uprobe *arch); -+extern void __weak arch_uprobe_disable_step(struct arch_uprobe *arch); - extern int uprobe_post_sstep_notifier(struct pt_regs *regs); - extern int uprobe_pre_sstep_notifier(struct pt_regs *regs); - extern void uprobe_notify_resume(struct pt_regs *regs); - extern bool uprobe_deny_signal(void); - extern bool __weak arch_uprobe_skip_sstep(struct arch_uprobe *aup, struct pt_regs *regs); - extern void uprobe_clear_state(struct mm_struct *mm); --extern void uprobe_reset_state(struct mm_struct *mm); - #else /* !CONFIG_UPROBES */ - struct uprobes_state { - }; -@@ -138,6 +129,10 @@ static inline void - uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end) - { - } -+static inline void -+uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) -+{ -+} - static inline void uprobe_notify_resume(struct pt_regs *regs) - { - } -@@ -158,8 +153,5 @@ static inline void uprobe_copy_process(struct task_struct *t) - static inline void uprobe_clear_state(struct mm_struct *mm) - { - } --static inline void uprobe_reset_state(struct mm_struct *mm) --{ --} - #endif /* !CONFIG_UPROBES */ - #endif /* _LINUX_UPROBES_H */ -diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c -index c08a22d..e933f65 100644 ---- a/kernel/events/uprobes.c -+++ b/kernel/events/uprobes.c -@@ -27,6 +27,7 @@ - #include /* read_mapping_page */ - #include - #include -+#include - #include /* anon_vma_prepare */ - #include /* set_pte_at_notify */ - #include /* try_to_free_swap */ -@@ -78,15 +79,23 @@ static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ]; - */ - static atomic_t uprobe_events = ATOMIC_INIT(0); - -+/* Have a copy of original instruction */ -+#define UPROBE_COPY_INSN 0 -+/* Dont run handlers when first register/ last unregister in progress*/ -+#define UPROBE_RUN_HANDLER 1 -+/* Can skip singlestep */ -+#define UPROBE_SKIP_SSTEP 2 -+ - struct uprobe { - struct rb_node rb_node; /* node in the rb tree */ - atomic_t ref; - struct rw_semaphore consumer_rwsem; -+ struct mutex copy_mutex; /* TODO: kill me and UPROBE_COPY_INSN */ - struct list_head pending_list; - struct uprobe_consumer *consumers; - struct inode *inode; /* Also hold a ref to inode */ - loff_t offset; -- int flags; -+ unsigned long flags; - struct arch_uprobe arch; - }; - -@@ -100,17 +109,12 @@ struct uprobe { - */ - static bool valid_vma(struct vm_area_struct *vma, bool is_register) - { -- if (!vma->vm_file) -- return false; -+ vm_flags_t flags = VM_HUGETLB | VM_MAYEXEC | VM_SHARED; - -- if (!is_register) -- return true; -+ if (is_register) -+ flags |= VM_WRITE; - -- if ((vma->vm_flags & (VM_HUGETLB|VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) -- == (VM_READ|VM_EXEC)) -- return true; -- -- return false; -+ return vma->vm_file && (vma->vm_flags & flags) == VM_MAYEXEC; - } - - static unsigned long offset_to_vaddr(struct vm_area_struct *vma, loff_t offset) -@@ -188,19 +192,44 @@ bool __weak is_swbp_insn(uprobe_opcode_t *insn) - return *insn == UPROBE_SWBP_INSN; - } - -+static void copy_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t *opcode) -+{ -+ void *kaddr = kmap_atomic(page); -+ memcpy(opcode, kaddr + (vaddr & ~PAGE_MASK), UPROBE_SWBP_INSN_SIZE); -+ kunmap_atomic(kaddr); -+} -+ -+static int verify_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t *new_opcode) -+{ -+ uprobe_opcode_t old_opcode; -+ bool is_swbp; -+ -+ copy_opcode(page, vaddr, &old_opcode); -+ is_swbp = is_swbp_insn(&old_opcode); -+ -+ if (is_swbp_insn(new_opcode)) { -+ if (is_swbp) /* register: already installed? */ -+ return 0; -+ } else { -+ if (!is_swbp) /* unregister: was it changed by us? */ -+ return 0; -+ } -+ -+ return 1; -+} -+ - /* - * NOTE: - * Expect the breakpoint instruction to be the smallest size instruction for - * the architecture. If an arch has variable length instruction and the - * breakpoint instruction is not of the smallest length instruction -- * supported by that architecture then we need to modify read_opcode / -+ * supported by that architecture then we need to modify is_swbp_at_addr and - * write_opcode accordingly. This would never be a problem for archs that - * have fixed length instructions. - */ - - /* - * write_opcode - write the opcode at a given virtual address. -- * @auprobe: arch breakpointing information. - * @mm: the probed process address space. - * @vaddr: the virtual address to store the opcode. - * @opcode: opcode to be written at @vaddr. -@@ -211,8 +240,8 @@ bool __weak is_swbp_insn(uprobe_opcode_t *insn) - * For mm @mm, write the opcode at @vaddr. - * Return 0 (success) or a negative errno. - */ --static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, -- unsigned long vaddr, uprobe_opcode_t opcode) -+static int write_opcode(struct mm_struct *mm, unsigned long vaddr, -+ uprobe_opcode_t opcode) - { - struct page *old_page, *new_page; - void *vaddr_old, *vaddr_new; -@@ -221,10 +250,14 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, - - retry: - /* Read the page with vaddr into memory */ -- ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma); -+ ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &old_page, &vma); - if (ret <= 0) - return ret; - -+ ret = verify_opcode(old_page, vaddr, &opcode); -+ if (ret <= 0) -+ goto put_old; -+ - ret = -ENOMEM; - new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr); - if (!new_page) -@@ -259,65 +292,6 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, - } - - /** -- * read_opcode - read the opcode at a given virtual address. -- * @mm: the probed process address space. -- * @vaddr: the virtual address to read the opcode. -- * @opcode: location to store the read opcode. -- * -- * Called with mm->mmap_sem held (for read and with a reference to -- * mm. -- * -- * For mm @mm, read the opcode at @vaddr and store it in @opcode. -- * Return 0 (success) or a negative errno. -- */ --static int read_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t *opcode) --{ -- struct page *page; -- void *vaddr_new; -- int ret; -- -- ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL); -- if (ret <= 0) -- return ret; -- -- lock_page(page); -- vaddr_new = kmap_atomic(page); -- vaddr &= ~PAGE_MASK; -- memcpy(opcode, vaddr_new + vaddr, UPROBE_SWBP_INSN_SIZE); -- kunmap_atomic(vaddr_new); -- unlock_page(page); -- -- put_page(page); -- -- return 0; --} -- --static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr) --{ -- uprobe_opcode_t opcode; -- int result; -- -- if (current->mm == mm) { -- pagefault_disable(); -- result = __copy_from_user_inatomic(&opcode, (void __user*)vaddr, -- sizeof(opcode)); -- pagefault_enable(); -- -- if (likely(result == 0)) -- goto out; -- } -- -- result = read_opcode(mm, vaddr, &opcode); -- if (result) -- return result; --out: -- if (is_swbp_insn(&opcode)) -- return 1; -- -- return 0; --} -- --/** - * set_swbp - store breakpoint at a given address. - * @auprobe: arch specific probepoint information. - * @mm: the probed process address space. -@@ -328,18 +302,7 @@ static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr) - */ - int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr) - { -- int result; -- /* -- * See the comment near uprobes_hash(). -- */ -- result = is_swbp_at_addr(mm, vaddr); -- if (result == 1) -- return -EEXIST; -- -- if (result) -- return result; -- -- return write_opcode(auprobe, mm, vaddr, UPROBE_SWBP_INSN); -+ return write_opcode(mm, vaddr, UPROBE_SWBP_INSN); - } - - /** -@@ -347,25 +310,14 @@ int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned - * @mm: the probed process address space. - * @auprobe: arch specific probepoint information. - * @vaddr: the virtual address to insert the opcode. -- * @verify: if true, verify existance of breakpoint instruction. - * - * For mm @mm, restore the original opcode (opcode) at @vaddr. - * Return 0 (success) or a negative errno. - */ - int __weak --set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr, bool verify) -+set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr) - { -- if (verify) { -- int result; -- -- result = is_swbp_at_addr(mm, vaddr); -- if (!result) -- return -EINVAL; -- -- if (result != 1) -- return result; -- } -- return write_opcode(auprobe, mm, vaddr, *(uprobe_opcode_t *)auprobe->insn); -+ return write_opcode(mm, vaddr, *(uprobe_opcode_t *)auprobe->insn); - } - - static int match_uprobe(struct uprobe *l, struct uprobe *r) -@@ -415,11 +367,10 @@ static struct uprobe *__find_uprobe(struct inode *inode, loff_t offset) - static struct uprobe *find_uprobe(struct inode *inode, loff_t offset) - { - struct uprobe *uprobe; -- unsigned long flags; - -- spin_lock_irqsave(&uprobes_treelock, flags); -+ spin_lock(&uprobes_treelock); - uprobe = __find_uprobe(inode, offset); -- spin_unlock_irqrestore(&uprobes_treelock, flags); -+ spin_unlock(&uprobes_treelock); - - return uprobe; - } -@@ -466,15 +417,14 @@ static struct uprobe *__insert_uprobe(struct uprobe *uprobe) - */ - static struct uprobe *insert_uprobe(struct uprobe *uprobe) - { -- unsigned long flags; - struct uprobe *u; - -- spin_lock_irqsave(&uprobes_treelock, flags); -+ spin_lock(&uprobes_treelock); - u = __insert_uprobe(uprobe); -- spin_unlock_irqrestore(&uprobes_treelock, flags); -+ spin_unlock(&uprobes_treelock); - - /* For now assume that the instruction need not be single-stepped */ -- uprobe->flags |= UPROBE_SKIP_SSTEP; -+ __set_bit(UPROBE_SKIP_SSTEP, &uprobe->flags); - - return u; - } -@@ -496,6 +446,7 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset) - uprobe->inode = igrab(inode); - uprobe->offset = offset; - init_rwsem(&uprobe->consumer_rwsem); -+ mutex_init(&uprobe->copy_mutex); - - /* add to uprobes_tree, sorted on inode:offset */ - cur_uprobe = insert_uprobe(uprobe); -@@ -516,7 +467,7 @@ static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs) - { - struct uprobe_consumer *uc; - -- if (!(uprobe->flags & UPROBE_RUN_HANDLER)) -+ if (!test_bit(UPROBE_RUN_HANDLER, &uprobe->flags)) - return; - - down_read(&uprobe->consumer_rwsem); -@@ -622,33 +573,48 @@ static int copy_insn(struct uprobe *uprobe, struct file *filp) - return __copy_insn(mapping, filp, uprobe->arch.insn, bytes, uprobe->offset); - } - --/* -- * How mm->uprobes_state.count gets updated -- * uprobe_mmap() increments the count if -- * - it successfully adds a breakpoint. -- * - it cannot add a breakpoint, but sees that there is a underlying -- * breakpoint (via a is_swbp_at_addr()). -- * -- * uprobe_munmap() decrements the count if -- * - it sees a underlying breakpoint, (via is_swbp_at_addr) -- * (Subsequent uprobe_unregister wouldnt find the breakpoint -- * unless a uprobe_mmap kicks in, since the old vma would be -- * dropped just after uprobe_munmap.) -- * -- * uprobe_register increments the count if: -- * - it successfully adds a breakpoint. -- * -- * uprobe_unregister decrements the count if: -- * - it sees a underlying breakpoint and removes successfully. -- * (via is_swbp_at_addr) -- * (Subsequent uprobe_munmap wouldnt find the breakpoint -- * since there is no underlying breakpoint after the -- * breakpoint removal.) -- */ -+static int prepare_uprobe(struct uprobe *uprobe, struct file *file, -+ struct mm_struct *mm, unsigned long vaddr) -+{ -+ int ret = 0; -+ -+ if (test_bit(UPROBE_COPY_INSN, &uprobe->flags)) -+ return ret; -+ -+ mutex_lock(&uprobe->copy_mutex); -+ if (test_bit(UPROBE_COPY_INSN, &uprobe->flags)) -+ goto out; -+ -+ ret = copy_insn(uprobe, file); -+ if (ret) -+ goto out; -+ -+ ret = -ENOTSUPP; -+ if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn)) -+ goto out; -+ -+ ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, vaddr); -+ if (ret) -+ goto out; -+ -+ /* write_opcode() assumes we don't cross page boundary */ -+ BUG_ON((uprobe->offset & ~PAGE_MASK) + -+ UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); -+ -+ smp_wmb(); /* pairs with rmb() in find_active_uprobe() */ -+ set_bit(UPROBE_COPY_INSN, &uprobe->flags); -+ -+ out: -+ mutex_unlock(&uprobe->copy_mutex); -+ -+ return ret; -+} -+ - static int - install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, - struct vm_area_struct *vma, unsigned long vaddr) - { -+ bool first_uprobe; - int ret; - - /* -@@ -659,48 +625,38 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, - * Hence behave as if probe already existed. - */ - if (!uprobe->consumers) -- return -EEXIST; -- -- if (!(uprobe->flags & UPROBE_COPY_INSN)) { -- ret = copy_insn(uprobe, vma->vm_file); -- if (ret) -- return ret; -- -- if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn)) -- return -ENOTSUPP; -- -- ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, vaddr); -- if (ret) -- return ret; -- -- /* write_opcode() assumes we don't cross page boundary */ -- BUG_ON((uprobe->offset & ~PAGE_MASK) + -- UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); -+ return 0; - -- uprobe->flags |= UPROBE_COPY_INSN; -- } -+ ret = prepare_uprobe(uprobe, vma->vm_file, mm, vaddr); -+ if (ret) -+ return ret; - - /* -- * Ideally, should be updating the probe count after the breakpoint -- * has been successfully inserted. However a thread could hit the -- * breakpoint we just inserted even before the probe count is -- * incremented. If this is the first breakpoint placed, breakpoint -- * notifier might ignore uprobes and pass the trap to the thread. -- * Hence increment before and decrement on failure. -+ * set MMF_HAS_UPROBES in advance for uprobe_pre_sstep_notifier(), -+ * the task can hit this breakpoint right after __replace_page(). - */ -- atomic_inc(&mm->uprobes_state.count); -+ first_uprobe = !test_bit(MMF_HAS_UPROBES, &mm->flags); -+ if (first_uprobe) -+ set_bit(MMF_HAS_UPROBES, &mm->flags); -+ - ret = set_swbp(&uprobe->arch, mm, vaddr); -- if (ret) -- atomic_dec(&mm->uprobes_state.count); -+ if (!ret) -+ clear_bit(MMF_RECALC_UPROBES, &mm->flags); -+ else if (first_uprobe) -+ clear_bit(MMF_HAS_UPROBES, &mm->flags); - - return ret; - } - --static void -+static int - remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, unsigned long vaddr) - { -- if (!set_orig_insn(&uprobe->arch, mm, vaddr, true)) -- atomic_dec(&mm->uprobes_state.count); -+ /* can happen if uprobe_register() fails */ -+ if (!test_bit(MMF_HAS_UPROBES, &mm->flags)) -+ return 0; -+ -+ set_bit(MMF_RECALC_UPROBES, &mm->flags); -+ return set_orig_insn(&uprobe->arch, mm, vaddr); - } - - /* -@@ -710,11 +666,9 @@ remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, unsigned long vad - */ - static void delete_uprobe(struct uprobe *uprobe) - { -- unsigned long flags; -- -- spin_lock_irqsave(&uprobes_treelock, flags); -+ spin_lock(&uprobes_treelock); - rb_erase(&uprobe->rb_node, &uprobes_tree); -- spin_unlock_irqrestore(&uprobes_treelock, flags); -+ spin_unlock(&uprobes_treelock); - iput(uprobe->inode); - put_uprobe(uprobe); - atomic_dec(&uprobe_events); -@@ -818,7 +772,7 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register) - struct mm_struct *mm = info->mm; - struct vm_area_struct *vma; - -- if (err) -+ if (err && is_register) - goto free; - - down_write(&mm->mmap_sem); -@@ -831,17 +785,11 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register) - vaddr_to_offset(vma, info->vaddr) != uprobe->offset) - goto unlock; - -- if (is_register) { -+ if (is_register) - err = install_breakpoint(uprobe, mm, vma, info->vaddr); -- /* -- * We can race against uprobe_mmap(), see the -- * comment near uprobe_hash(). -- */ -- if (err == -EEXIST) -- err = 0; -- } else { -- remove_breakpoint(uprobe, mm, info->vaddr); -- } -+ else -+ err |= remove_breakpoint(uprobe, mm, info->vaddr); -+ - unlock: - up_write(&mm->mmap_sem); - free: -@@ -897,21 +845,25 @@ int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer * - mutex_lock(uprobes_hash(inode)); - uprobe = alloc_uprobe(inode, offset); - -- if (uprobe && !consumer_add(uprobe, uc)) { -+ if (!uprobe) { -+ ret = -ENOMEM; -+ } else if (!consumer_add(uprobe, uc)) { - ret = __uprobe_register(uprobe); - if (ret) { - uprobe->consumers = NULL; - __uprobe_unregister(uprobe); - } else { -- uprobe->flags |= UPROBE_RUN_HANDLER; -+ set_bit(UPROBE_RUN_HANDLER, &uprobe->flags); - } - } - - mutex_unlock(uprobes_hash(inode)); -- put_uprobe(uprobe); -+ if (uprobe) -+ put_uprobe(uprobe); - - return ret; - } -+EXPORT_SYMBOL_GPL(uprobe_register); - - /* - * uprobe_unregister - unregister a already registered probe. -@@ -935,7 +887,7 @@ void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consume - if (consumer_del(uprobe, uc)) { - if (!uprobe->consumers) { - __uprobe_unregister(uprobe); -- uprobe->flags &= ~UPROBE_RUN_HANDLER; -+ clear_bit(UPROBE_RUN_HANDLER, &uprobe->flags); - } - } - -@@ -943,6 +895,7 @@ void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consume - if (uprobe) - put_uprobe(uprobe); - } -+EXPORT_SYMBOL_GPL(uprobe_unregister); - - static struct rb_node * - find_node_in_range(struct inode *inode, loff_t min, loff_t max) -@@ -978,7 +931,6 @@ static void build_probe_list(struct inode *inode, - struct list_head *head) - { - loff_t min, max; -- unsigned long flags; - struct rb_node *n, *t; - struct uprobe *u; - -@@ -986,7 +938,7 @@ static void build_probe_list(struct inode *inode, - min = vaddr_to_offset(vma, start); - max = min + (end - start) - 1; - -- spin_lock_irqsave(&uprobes_treelock, flags); -+ spin_lock(&uprobes_treelock); - n = find_node_in_range(inode, min, max); - if (n) { - for (t = n; t; t = rb_prev(t)) { -@@ -1004,27 +956,20 @@ static void build_probe_list(struct inode *inode, - atomic_inc(&u->ref); - } - } -- spin_unlock_irqrestore(&uprobes_treelock, flags); -+ spin_unlock(&uprobes_treelock); - } - - /* -- * Called from mmap_region. -- * called with mm->mmap_sem acquired. -- * -- * Return -ve no if we fail to insert probes and we cannot -- * bail-out. -- * Return 0 otherwise. i.e: -+ * Called from mmap_region/vma_adjust with mm->mmap_sem acquired. - * -- * - successful insertion of probes -- * - (or) no possible probes to be inserted. -- * - (or) insertion of probes failed but we can bail-out. -+ * Currently we ignore all errors and always return 0, the callers -+ * can't handle the failure anyway. - */ - int uprobe_mmap(struct vm_area_struct *vma) - { - struct list_head tmp_list; - struct uprobe *uprobe, *u; - struct inode *inode; -- int ret, count; - - if (!atomic_read(&uprobe_events) || !valid_vma(vma, true)) - return 0; -@@ -1036,44 +981,35 @@ int uprobe_mmap(struct vm_area_struct *vma) - mutex_lock(uprobes_mmap_hash(inode)); - build_probe_list(inode, vma, vma->vm_start, vma->vm_end, &tmp_list); - -- ret = 0; -- count = 0; -- - list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) { -- if (!ret) { -+ if (!fatal_signal_pending(current)) { - unsigned long vaddr = offset_to_vaddr(vma, uprobe->offset); -- -- ret = install_breakpoint(uprobe, vma->vm_mm, vma, vaddr); -- /* -- * We can race against uprobe_register(), see the -- * comment near uprobe_hash(). -- */ -- if (ret == -EEXIST) { -- ret = 0; -- -- if (!is_swbp_at_addr(vma->vm_mm, vaddr)) -- continue; -- -- /* -- * Unable to insert a breakpoint, but -- * breakpoint lies underneath. Increment the -- * probe count. -- */ -- atomic_inc(&vma->vm_mm->uprobes_state.count); -- } -- -- if (!ret) -- count++; -+ install_breakpoint(uprobe, vma->vm_mm, vma, vaddr); - } - put_uprobe(uprobe); - } -- - mutex_unlock(uprobes_mmap_hash(inode)); - -- if (ret) -- atomic_sub(count, &vma->vm_mm->uprobes_state.count); -+ return 0; -+} - -- return ret; -+static bool -+vma_has_uprobes(struct vm_area_struct *vma, unsigned long start, unsigned long end) -+{ -+ loff_t min, max; -+ struct inode *inode; -+ struct rb_node *n; -+ -+ inode = vma->vm_file->f_mapping->host; -+ -+ min = vaddr_to_offset(vma, start); -+ max = min + (end - start) - 1; -+ -+ spin_lock(&uprobes_treelock); -+ n = find_node_in_range(inode, min, max); -+ spin_unlock(&uprobes_treelock); -+ -+ return !!n; - } - - /* -@@ -1081,37 +1017,18 @@ int uprobe_mmap(struct vm_area_struct *vma) - */ - void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end) - { -- struct list_head tmp_list; -- struct uprobe *uprobe, *u; -- struct inode *inode; -- - if (!atomic_read(&uprobe_events) || !valid_vma(vma, false)) - return; - - if (!atomic_read(&vma->vm_mm->mm_users)) /* called by mmput() ? */ - return; - -- if (!atomic_read(&vma->vm_mm->uprobes_state.count)) -- return; -- -- inode = vma->vm_file->f_mapping->host; -- if (!inode) -+ if (!test_bit(MMF_HAS_UPROBES, &vma->vm_mm->flags) || -+ test_bit(MMF_RECALC_UPROBES, &vma->vm_mm->flags)) - return; - -- mutex_lock(uprobes_mmap_hash(inode)); -- build_probe_list(inode, vma, start, end, &tmp_list); -- -- list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) { -- unsigned long vaddr = offset_to_vaddr(vma, uprobe->offset); -- /* -- * An unregister could have removed the probe before -- * unmap. So check before we decrement the count. -- */ -- if (is_swbp_at_addr(vma->vm_mm, vaddr) == 1) -- atomic_dec(&vma->vm_mm->uprobes_state.count); -- put_uprobe(uprobe); -- } -- mutex_unlock(uprobes_mmap_hash(inode)); -+ if (vma_has_uprobes(vma, start, end)) -+ set_bit(MMF_RECALC_UPROBES, &vma->vm_mm->flags); - } - - /* Slot allocation for XOL */ -@@ -1213,13 +1130,15 @@ void uprobe_clear_state(struct mm_struct *mm) - kfree(area); - } - --/* -- * uprobe_reset_state - Free the area allocated for slots. -- */ --void uprobe_reset_state(struct mm_struct *mm) -+void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) - { -- mm->uprobes_state.xol_area = NULL; -- atomic_set(&mm->uprobes_state.count, 0); -+ newmm->uprobes_state.xol_area = NULL; -+ -+ if (test_bit(MMF_HAS_UPROBES, &oldmm->flags)) { -+ set_bit(MMF_HAS_UPROBES, &newmm->flags); -+ /* unconditionally, dup_mmap() skips VM_DONTCOPY vmas */ -+ set_bit(MMF_RECALC_UPROBES, &newmm->flags); -+ } - } - - /* -@@ -1430,13 +1349,57 @@ bool uprobe_deny_signal(void) - */ - static bool can_skip_sstep(struct uprobe *uprobe, struct pt_regs *regs) - { -- if (arch_uprobe_skip_sstep(&uprobe->arch, regs)) -- return true; -- -- uprobe->flags &= ~UPROBE_SKIP_SSTEP; -+ if (test_bit(UPROBE_SKIP_SSTEP, &uprobe->flags)) { -+ if (arch_uprobe_skip_sstep(&uprobe->arch, regs)) -+ return true; -+ clear_bit(UPROBE_SKIP_SSTEP, &uprobe->flags); -+ } - return false; - } - -+static void mmf_recalc_uprobes(struct mm_struct *mm) -+{ -+ struct vm_area_struct *vma; -+ -+ for (vma = mm->mmap; vma; vma = vma->vm_next) { -+ if (!valid_vma(vma, false)) -+ continue; -+ /* -+ * This is not strictly accurate, we can race with -+ * uprobe_unregister() and see the already removed -+ * uprobe if delete_uprobe() was not yet called. -+ */ -+ if (vma_has_uprobes(vma, vma->vm_start, vma->vm_end)) -+ return; -+ } -+ -+ clear_bit(MMF_HAS_UPROBES, &mm->flags); -+} -+ -+static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr) -+{ -+ struct page *page; -+ uprobe_opcode_t opcode; -+ int result; -+ -+ pagefault_disable(); -+ result = __copy_from_user_inatomic(&opcode, (void __user*)vaddr, -+ sizeof(opcode)); -+ pagefault_enable(); -+ -+ if (likely(result == 0)) -+ goto out; -+ -+ result = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL); -+ if (result < 0) -+ return result; -+ -+ copy_opcode(page, vaddr, &opcode); -+ put_page(page); -+ out: -+ return is_swbp_insn(&opcode); -+} -+ - static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp) - { - struct mm_struct *mm = current->mm; -@@ -1458,11 +1421,24 @@ static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp) - } else { - *is_swbp = -EFAULT; - } -+ -+ if (!uprobe && test_and_clear_bit(MMF_RECALC_UPROBES, &mm->flags)) -+ mmf_recalc_uprobes(mm); - up_read(&mm->mmap_sem); - - return uprobe; - } - -+void __weak arch_uprobe_enable_step(struct arch_uprobe *arch) -+{ -+ user_enable_single_step(current); -+} -+ -+void __weak arch_uprobe_disable_step(struct arch_uprobe *arch) -+{ -+ user_disable_single_step(current); -+} -+ - /* - * Run handler and ask thread to singlestep. - * Ensure all non-fatal signals cannot interrupt thread while it singlesteps. -@@ -1494,41 +1470,42 @@ static void handle_swbp(struct pt_regs *regs) - } - return; - } -+ /* -+ * TODO: move copy_insn/etc into _register and remove this hack. -+ * After we hit the bp, _unregister + _register can install the -+ * new and not-yet-analyzed uprobe at the same address, restart. -+ */ -+ smp_rmb(); /* pairs with wmb() in install_breakpoint() */ -+ if (unlikely(!test_bit(UPROBE_COPY_INSN, &uprobe->flags))) -+ goto restart; - - utask = current->utask; - if (!utask) { - utask = add_utask(); - /* Cannot allocate; re-execute the instruction. */ - if (!utask) -- goto cleanup_ret; -+ goto restart; - } -- utask->active_uprobe = uprobe; -+ - handler_chain(uprobe, regs); -- if (uprobe->flags & UPROBE_SKIP_SSTEP && can_skip_sstep(uprobe, regs)) -- goto cleanup_ret; -+ if (can_skip_sstep(uprobe, regs)) -+ goto out; - -- utask->state = UTASK_SSTEP; - if (!pre_ssout(uprobe, regs, bp_vaddr)) { -- user_enable_single_step(current); -+ arch_uprobe_enable_step(&uprobe->arch); -+ utask->active_uprobe = uprobe; -+ utask->state = UTASK_SSTEP; - return; - } - --cleanup_ret: -- if (utask) { -- utask->active_uprobe = NULL; -- utask->state = UTASK_RUNNING; -- } -- if (uprobe) { -- if (!(uprobe->flags & UPROBE_SKIP_SSTEP)) -- -- /* -- * cannot singlestep; cannot skip instruction; -- * re-execute the instruction. -- */ -- instruction_pointer_set(regs, bp_vaddr); -- -- put_uprobe(uprobe); -- } -+restart: -+ /* -+ * cannot singlestep; cannot skip instruction; -+ * re-execute the instruction. -+ */ -+ instruction_pointer_set(regs, bp_vaddr); -+out: -+ put_uprobe(uprobe); - } - - /* -@@ -1547,10 +1524,10 @@ static void handle_singlestep(struct uprobe_task *utask, struct pt_regs *regs) - else - WARN_ON_ONCE(1); - -+ arch_uprobe_disable_step(&uprobe->arch); - put_uprobe(uprobe); - utask->active_uprobe = NULL; - utask->state = UTASK_RUNNING; -- user_disable_single_step(current); - xol_free_insn_slot(current); - - spin_lock_irq(¤t->sighand->siglock); -@@ -1559,13 +1536,12 @@ static void handle_singlestep(struct uprobe_task *utask, struct pt_regs *regs) - } - - /* -- * On breakpoint hit, breakpoint notifier sets the TIF_UPROBE flag. (and on -- * subsequent probe hits on the thread sets the state to UTASK_BP_HIT) and -- * allows the thread to return from interrupt. -+ * On breakpoint hit, breakpoint notifier sets the TIF_UPROBE flag and -+ * allows the thread to return from interrupt. After that handle_swbp() -+ * sets utask->active_uprobe. - * -- * On singlestep exception, singlestep notifier sets the TIF_UPROBE flag and -- * also sets the state to UTASK_SSTEP_ACK and allows the thread to return from -- * interrupt. -+ * On singlestep exception, singlestep notifier sets the TIF_UPROBE flag -+ * and allows the thread to return from interrupt. - * - * While returning to userspace, thread notices the TIF_UPROBE flag and calls - * uprobe_notify_resume(). -@@ -1574,11 +1550,13 @@ void uprobe_notify_resume(struct pt_regs *regs) - { - struct uprobe_task *utask; - -+ clear_thread_flag(TIF_UPROBE); -+ - utask = current->utask; -- if (!utask || utask->state == UTASK_BP_HIT) -- handle_swbp(regs); -- else -+ if (utask && utask->active_uprobe) - handle_singlestep(utask, regs); -+ else -+ handle_swbp(regs); - } - - /* -@@ -1587,18 +1565,10 @@ void uprobe_notify_resume(struct pt_regs *regs) - */ - int uprobe_pre_sstep_notifier(struct pt_regs *regs) - { -- struct uprobe_task *utask; -- -- if (!current->mm || !atomic_read(¤t->mm->uprobes_state.count)) -- /* task is currently not uprobed */ -+ if (!current->mm || !test_bit(MMF_HAS_UPROBES, ¤t->mm->flags)) - return 0; - -- utask = current->utask; -- if (utask) -- utask->state = UTASK_BP_HIT; -- - set_thread_flag(TIF_UPROBE); -- - return 1; - } - -diff --git a/kernel/fork.c b/kernel/fork.c -index 2c8857e..2343c9e 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -353,6 +353,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) - - down_write(&oldmm->mmap_sem); - flush_cache_dup_mm(oldmm); -+ uprobe_dup_mmap(oldmm, mm); - /* - * Not linked in yet - no deadlock potential: - */ -@@ -454,9 +455,6 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) - - if (retval) - goto out; -- -- if (file) -- uprobe_mmap(tmp); - } - /* a new mm has just been created */ - arch_dup_mmap(oldmm, mm); -@@ -839,8 +837,6 @@ struct mm_struct *dup_mm(struct task_struct *tsk) - #ifdef CONFIG_TRANSPARENT_HUGEPAGE - mm->pmd_huge_pte = NULL; - #endif -- uprobe_reset_state(mm); -- - if (!mm_init(mm, tsk)) - goto fail_nomem; - -diff --git a/kernel/ptrace.c b/kernel/ptrace.c -index a232bb5..764fcd1 100644 ---- a/kernel/ptrace.c -+++ b/kernel/ptrace.c -@@ -33,6 +33,12 @@ static int ptrace_trapping_sleep_fn(void *flags) - } - - /* -+ * This is declared in linux/regset.h and defined in machine-dependent -+ * code. We put the export here to ensure no machine forgets it. -+ */ -+EXPORT_SYMBOL_GPL(task_user_regset_view); -+ -+/* - * ptrace a task: make the debugger its new parent and - * move it to the ptrace list. - * -_______________________________________________ -kernel mailing list -kernel@lists.fedoraproject.org -https://admin.fedoraproject.org/mailman/listinfo/kernel