block/fs: make tracking dirty task debug only
Adding a new element "tsk_dirty" to struct page increases the size of mem_map/vmemmap, restrict this to a debug only functionality to save few MB of memory. Considering a system with 1G of RAM, there will be nearly 262144 pages and thus that many number of page structures in mem_map/vmemmap. With pointer size of 8 bytes on a 64 bit system, adding this pointer to "struct page" means an increase of "2MB" for mem_map. CRs-Fixed: 738692 Change-Id: Idf3217dcbe17cf1ab4d462d2aa8d39da1ffd8b13 Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org> [venkatg@codeaurora.org: Fixed trivial merge conflict] Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
This commit is contained in:
parent
014929f975
commit
a627c73479
3 changed files with 38 additions and 12 deletions
|
@ -2081,6 +2081,27 @@ out:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(generic_make_request);
|
EXPORT_SYMBOL(generic_make_request);
|
||||||
|
|
||||||
|
#ifdef CONFIG_BLK_DEV_IO_TRACE
|
||||||
|
static inline struct task_struct *get_dirty_task(struct bio *bio)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Not all the pages in the bio are dirtied by the
|
||||||
|
* same task but most likely it will be, since the
|
||||||
|
* sectors accessed on the device must be adjacent.
|
||||||
|
*/
|
||||||
|
if (bio->bi_io_vec && bio->bi_io_vec->bv_page &&
|
||||||
|
bio->bi_io_vec->bv_page->tsk_dirty)
|
||||||
|
return bio->bi_io_vec->bv_page->tsk_dirty;
|
||||||
|
else
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline struct task_struct *get_dirty_task(struct bio *bio)
|
||||||
|
{
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* submit_bio - submit a bio to the block device layer for I/O
|
* submit_bio - submit a bio to the block device layer for I/O
|
||||||
* @rw: whether to %READ or %WRITE, or maybe to %READA (read ahead)
|
* @rw: whether to %READ or %WRITE, or maybe to %READA (read ahead)
|
||||||
|
@ -2093,7 +2114,6 @@ EXPORT_SYMBOL(generic_make_request);
|
||||||
*/
|
*/
|
||||||
blk_qc_t submit_bio(int rw, struct bio *bio)
|
blk_qc_t submit_bio(int rw, struct bio *bio)
|
||||||
{
|
{
|
||||||
struct task_struct *tsk = current;
|
|
||||||
bio->bi_rw |= rw;
|
bio->bi_rw |= rw;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2117,16 +2137,9 @@ blk_qc_t submit_bio(int rw, struct bio *bio)
|
||||||
|
|
||||||
if (unlikely(block_dump)) {
|
if (unlikely(block_dump)) {
|
||||||
char b[BDEVNAME_SIZE];
|
char b[BDEVNAME_SIZE];
|
||||||
|
struct task_struct *tsk;
|
||||||
|
|
||||||
/*
|
tsk = get_dirty_task(bio);
|
||||||
* Not all the pages in the bio are dirtied by the
|
|
||||||
* same task but most likely it will be, since the
|
|
||||||
* sectors accessed on the device must be adjacent.
|
|
||||||
*/
|
|
||||||
if (bio->bi_io_vec && bio->bi_io_vec->bv_page &&
|
|
||||||
bio->bi_io_vec->bv_page->tsk_dirty)
|
|
||||||
tsk = bio->bi_io_vec->bv_page->tsk_dirty;
|
|
||||||
|
|
||||||
printk(KERN_DEBUG "%s(%d): %s block %Lu on %s (%u sectors)\n",
|
printk(KERN_DEBUG "%s(%d): %s block %Lu on %s (%u sectors)\n",
|
||||||
tsk->comm, task_pid_nr(tsk),
|
tsk->comm, task_pid_nr(tsk),
|
||||||
(rw & WRITE) ? "WRITE" : "READ",
|
(rw & WRITE) ? "WRITE" : "READ",
|
||||||
|
|
15
fs/buffer.c
15
fs/buffer.c
|
@ -621,6 +621,18 @@ void mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mark_buffer_dirty_inode);
|
EXPORT_SYMBOL(mark_buffer_dirty_inode);
|
||||||
|
|
||||||
|
#ifdef CONFIG_BLK_DEV_IO_TRACE
|
||||||
|
static inline void save_dirty_task(struct page *page)
|
||||||
|
{
|
||||||
|
/* Save the task that is dirtying this page */
|
||||||
|
page->tsk_dirty = current;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline void save_dirty_task(struct page *page)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mark the page dirty, and set it dirty in the radix tree, and mark the inode
|
* Mark the page dirty, and set it dirty in the radix tree, and mark the inode
|
||||||
* dirty.
|
* dirty.
|
||||||
|
@ -641,8 +653,7 @@ static void __set_page_dirty(struct page *page, struct address_space *mapping,
|
||||||
account_page_dirtied(page, mapping, memcg);
|
account_page_dirtied(page, mapping, memcg);
|
||||||
radix_tree_tag_set(&mapping->page_tree,
|
radix_tree_tag_set(&mapping->page_tree,
|
||||||
page_index(page), PAGECACHE_TAG_DIRTY);
|
page_index(page), PAGECACHE_TAG_DIRTY);
|
||||||
/* Save the task that is dirtying this page */
|
save_dirty_task(page);
|
||||||
page->tsk_dirty = current;
|
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&mapping->tree_lock, flags);
|
spin_unlock_irqrestore(&mapping->tree_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,7 +207,9 @@ struct page {
|
||||||
not kmapped, ie. highmem) */
|
not kmapped, ie. highmem) */
|
||||||
#endif /* WANT_PAGE_VIRTUAL */
|
#endif /* WANT_PAGE_VIRTUAL */
|
||||||
|
|
||||||
|
#ifdef CONFIG_BLK_DEV_IO_TRACE
|
||||||
struct task_struct *tsk_dirty; /* task that sets this page dirty */
|
struct task_struct *tsk_dirty; /* task that sets this page dirty */
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_KMEMCHECK
|
#ifdef CONFIG_KMEMCHECK
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Reference in a new issue