diff options
-rw-r--r-- | fs/fs-writeback.c | 16 | ||||
-rw-r--r-- | include/linux/proportions.h | 4 | ||||
-rw-r--r-- | include/trace/events/writeback.h | 7 | ||||
-rw-r--r-- | mm/backing-dev.c | 23 |
4 files changed, 35 insertions, 15 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index f855916657ba..5b4a9362d5aa 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -53,14 +53,6 @@ struct wb_writeback_work { | |||
53 | }; | 53 | }; |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * Include the creation of the trace points after defining the | ||
57 | * wb_writeback_work structure so that the definition remains local to this | ||
58 | * file. | ||
59 | */ | ||
60 | #define CREATE_TRACE_POINTS | ||
61 | #include <trace/events/writeback.h> | ||
62 | |||
63 | /* | ||
64 | * We don't actually have pdflush, but this one is exported though /proc... | 56 | * We don't actually have pdflush, but this one is exported though /proc... |
65 | */ | 57 | */ |
66 | int nr_pdflush_threads; | 58 | int nr_pdflush_threads; |
@@ -92,6 +84,14 @@ static inline struct inode *wb_inode(struct list_head *head) | |||
92 | return list_entry(head, struct inode, i_wb_list); | 84 | return list_entry(head, struct inode, i_wb_list); |
93 | } | 85 | } |
94 | 86 | ||
87 | /* | ||
88 | * Include the creation of the trace points after defining the | ||
89 | * wb_writeback_work structure and inline functions so that the definition | ||
90 | * remains local to this file. | ||
91 | */ | ||
92 | #define CREATE_TRACE_POINTS | ||
93 | #include <trace/events/writeback.h> | ||
94 | |||
95 | /* Wakeup flusher thread or forker thread to fork it. Requires bdi->wb_lock. */ | 95 | /* Wakeup flusher thread or forker thread to fork it. Requires bdi->wb_lock. */ |
96 | static void bdi_wakeup_flusher(struct backing_dev_info *bdi) | 96 | static void bdi_wakeup_flusher(struct backing_dev_info *bdi) |
97 | { | 97 | { |
diff --git a/include/linux/proportions.h b/include/linux/proportions.h index ef35bb73f69b..26a8a4ed9b07 100644 --- a/include/linux/proportions.h +++ b/include/linux/proportions.h | |||
@@ -81,7 +81,11 @@ void prop_inc_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl) | |||
81 | * Limit the time part in order to ensure there are some bits left for the | 81 | * Limit the time part in order to ensure there are some bits left for the |
82 | * cycle counter and fraction multiply. | 82 | * cycle counter and fraction multiply. |
83 | */ | 83 | */ |
84 | #if BITS_PER_LONG == 32 | ||
84 | #define PROP_MAX_SHIFT (3*BITS_PER_LONG/4) | 85 | #define PROP_MAX_SHIFT (3*BITS_PER_LONG/4) |
86 | #else | ||
87 | #define PROP_MAX_SHIFT (BITS_PER_LONG/2) | ||
88 | #endif | ||
85 | 89 | ||
86 | #define PROP_FRAC_SHIFT (BITS_PER_LONG - PROP_MAX_SHIFT - 1) | 90 | #define PROP_FRAC_SHIFT (BITS_PER_LONG - PROP_MAX_SHIFT - 1) |
87 | #define PROP_FRAC_BASE (1UL << PROP_FRAC_SHIFT) | 91 | #define PROP_FRAC_BASE (1UL << PROP_FRAC_SHIFT) |
diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h index 8588a8918023..5973410e8f8c 100644 --- a/include/trace/events/writeback.h +++ b/include/trace/events/writeback.h | |||
@@ -47,7 +47,10 @@ DECLARE_EVENT_CLASS(writeback_work_class, | |||
47 | __field(int, reason) | 47 | __field(int, reason) |
48 | ), | 48 | ), |
49 | TP_fast_assign( | 49 | TP_fast_assign( |
50 | strncpy(__entry->name, dev_name(bdi->dev), 32); | 50 | struct device *dev = bdi->dev; |
51 | if (!dev) | ||
52 | dev = default_backing_dev_info.dev; | ||
53 | strncpy(__entry->name, dev_name(dev), 32); | ||
51 | __entry->nr_pages = work->nr_pages; | 54 | __entry->nr_pages = work->nr_pages; |
52 | __entry->sb_dev = work->sb ? work->sb->s_dev : 0; | 55 | __entry->sb_dev = work->sb ? work->sb->s_dev : 0; |
53 | __entry->sync_mode = work->sync_mode; | 56 | __entry->sync_mode = work->sync_mode; |
@@ -426,7 +429,7 @@ DECLARE_EVENT_CLASS(writeback_single_inode_template, | |||
426 | 429 | ||
427 | TP_fast_assign( | 430 | TP_fast_assign( |
428 | strncpy(__entry->name, | 431 | strncpy(__entry->name, |
429 | dev_name(inode->i_mapping->backing_dev_info->dev), 32); | 432 | dev_name(inode_to_bdi(inode)->dev), 32); |
430 | __entry->ino = inode->i_ino; | 433 | __entry->ino = inode->i_ino; |
431 | __entry->state = inode->i_state; | 434 | __entry->state = inode->i_state; |
432 | __entry->dirtied_when = inode->dirtied_when; | 435 | __entry->dirtied_when = inode->dirtied_when; |
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 7ba8feae11b8..dd8e2aafb07e 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -318,7 +318,7 @@ static void wakeup_timer_fn(unsigned long data) | |||
318 | if (bdi->wb.task) { | 318 | if (bdi->wb.task) { |
319 | trace_writeback_wake_thread(bdi); | 319 | trace_writeback_wake_thread(bdi); |
320 | wake_up_process(bdi->wb.task); | 320 | wake_up_process(bdi->wb.task); |
321 | } else { | 321 | } else if (bdi->dev) { |
322 | /* | 322 | /* |
323 | * When bdi tasks are inactive for long time, they are killed. | 323 | * When bdi tasks are inactive for long time, they are killed. |
324 | * In this case we have to wake-up the forker thread which | 324 | * In this case we have to wake-up the forker thread which |
@@ -584,6 +584,8 @@ EXPORT_SYMBOL(bdi_register_dev); | |||
584 | */ | 584 | */ |
585 | static void bdi_wb_shutdown(struct backing_dev_info *bdi) | 585 | static void bdi_wb_shutdown(struct backing_dev_info *bdi) |
586 | { | 586 | { |
587 | struct task_struct *task; | ||
588 | |||
587 | if (!bdi_cap_writeback_dirty(bdi)) | 589 | if (!bdi_cap_writeback_dirty(bdi)) |
588 | return; | 590 | return; |
589 | 591 | ||
@@ -602,8 +604,13 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi) | |||
602 | * Finally, kill the kernel thread. We don't need to be RCU | 604 | * Finally, kill the kernel thread. We don't need to be RCU |
603 | * safe anymore, since the bdi is gone from visibility. | 605 | * safe anymore, since the bdi is gone from visibility. |
604 | */ | 606 | */ |
605 | if (bdi->wb.task) | 607 | spin_lock_bh(&bdi->wb_lock); |
606 | kthread_stop(bdi->wb.task); | 608 | task = bdi->wb.task; |
609 | bdi->wb.task = NULL; | ||
610 | spin_unlock_bh(&bdi->wb_lock); | ||
611 | |||
612 | if (task) | ||
613 | kthread_stop(task); | ||
607 | } | 614 | } |
608 | 615 | ||
609 | /* | 616 | /* |
@@ -623,7 +630,9 @@ static void bdi_prune_sb(struct backing_dev_info *bdi) | |||
623 | 630 | ||
624 | void bdi_unregister(struct backing_dev_info *bdi) | 631 | void bdi_unregister(struct backing_dev_info *bdi) |
625 | { | 632 | { |
626 | if (bdi->dev) { | 633 | struct device *dev = bdi->dev; |
634 | |||
635 | if (dev) { | ||
627 | bdi_set_min_ratio(bdi, 0); | 636 | bdi_set_min_ratio(bdi, 0); |
628 | trace_writeback_bdi_unregister(bdi); | 637 | trace_writeback_bdi_unregister(bdi); |
629 | bdi_prune_sb(bdi); | 638 | bdi_prune_sb(bdi); |
@@ -632,8 +641,12 @@ void bdi_unregister(struct backing_dev_info *bdi) | |||
632 | if (!bdi_cap_flush_forker(bdi)) | 641 | if (!bdi_cap_flush_forker(bdi)) |
633 | bdi_wb_shutdown(bdi); | 642 | bdi_wb_shutdown(bdi); |
634 | bdi_debug_unregister(bdi); | 643 | bdi_debug_unregister(bdi); |
635 | device_unregister(bdi->dev); | 644 | |
645 | spin_lock_bh(&bdi->wb_lock); | ||
636 | bdi->dev = NULL; | 646 | bdi->dev = NULL; |
647 | spin_unlock_bh(&bdi->wb_lock); | ||
648 | |||
649 | device_unregister(dev); | ||
637 | } | 650 | } |
638 | } | 651 | } |
639 | EXPORT_SYMBOL(bdi_unregister); | 652 | EXPORT_SYMBOL(bdi_unregister); |