From fd584fb6fa6d48e1fae1077d2ab0021ae9c98edf Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 10 Jul 2019 11:31:01 +0200 Subject: [PATCH] mm: migrate: Fix race with __find_get_block() Signed-off-by: Jan Kara --- include/trace/events/migrate.h | 42 ++++++++++++++++++++++++++++++++++++++++++ mm/migrate.c | 8 +++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/include/trace/events/migrate.h b/include/trace/events/migrate.h index 705b33d1e395..15473a508216 100644 --- a/include/trace/events/migrate.h +++ b/include/trace/events/migrate.h @@ -70,6 +70,48 @@ TRACE_EVENT(mm_migrate_pages, __print_symbolic(__entry->mode, MIGRATE_MODE), __print_symbolic(__entry->reason, MIGRATE_REASON)) ); + +TRACE_EVENT(mm_migrate_buffers_begin, + + TP_PROTO(struct address_space *mapping, unsigned long index), + + TP_ARGS(mapping, index), + + TP_STRUCT__entry( + __field(unsigned long, mapping) + __field(unsigned long, index) + ), + + TP_fast_assign( + __entry->mapping = (unsigned long)mapping; + __entry->index = index; + ), + + TP_printk("mapping=%lx index=%lu", __entry->mapping, __entry->index) +); + +TRACE_EVENT(mm_migrate_buffers_end, + + TP_PROTO(struct address_space *mapping, unsigned long index, int rc), + + TP_ARGS(mapping, index, rc), + + TP_STRUCT__entry( + __field(unsigned long, mapping) + __field(unsigned long, index) + __field(int, rc) + ), + + TP_fast_assign( + __entry->mapping = (unsigned long)mapping; + __entry->index = index; + __entry->rc = rc; + ), + + TP_printk("mapping=%lx index=%lu rc=%d", __entry->mapping, __entry->index, __entry->rc) +); + + #endif /* _TRACE_MIGRATE_H */ /* This part must be outside protection */ diff --git a/mm/migrate.c b/mm/migrate.c index e9594bc0d406..bce0f1b03a60 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -763,6 +763,7 @@ static int __buffer_migrate_page(struct address_space *mapping, recheck_buffers: busy = false; spin_lock(&mapping->private_lock); + trace_mm_migrate_buffers_begin(mapping, page->index); bh = head; do { if (atomic_read(&bh->b_count)) { @@ -771,12 +772,13 @@ static int __buffer_migrate_page(struct address_space *mapping, } bh = bh->b_this_page; } while (bh != head); - spin_unlock(&mapping->private_lock); if (busy) { if (invalidated) { rc = -EAGAIN; goto unlock_buffers; } + trace_mm_migrate_buffers_end(mapping, page->index, -EAGAIN); + spin_unlock(&mapping->private_lock); invalidate_bh_lrus(); invalidated = true; goto recheck_buffers; @@ -809,6 +811,10 @@ static int __buffer_migrate_page(struct address_space *mapping, rc = MIGRATEPAGE_SUCCESS; unlock_buffers: + if (check_refs) { + trace_mm_migrate_buffers_end(mapping, page->index, rc); + spin_unlock(&mapping->private_lock); + } bh = head; do { unlock_buffer(bh); -- 2.16.4