* [patch 00/14] Misc cleanups / fixes
@ 2007-09-25 23:25 Christoph Lameter
2007-09-25 23:25 ` [patch 01/14] Pagecache zeroing: zero_user_segment, zero_user_segments and zero_user Christoph Lameter
` (14 more replies)
0 siblings, 15 replies; 23+ messages in thread
From: Christoph Lameter @ 2007-09-25 23:25 UTC (permalink / raw)
To: akpm; +Cc: linux-mm
This is a collection of fixes and cleanups from the slab defrag,
virtual compound and the large block patchset that are useful
independent of these patchsets and that were rediffed against
2.6.23-rc8-mm1.
1+2 Page cache zeroing simplifications
3-8 vmalloc fixes
9-11 slub cleanups / fixes
12 General capability to take a refcount on a compound page
13 Dentry code consolidation
14 Revert buffer_head patch to get the constructor back.
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 23+ messages in thread* [patch 01/14] Pagecache zeroing: zero_user_segment, zero_user_segments and zero_user 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter @ 2007-09-25 23:25 ` Christoph Lameter 2007-09-25 23:25 ` [patch 02/14] Reiser4 portion of zero_user cleanup patch Christoph Lameter ` (13 subsequent siblings) 14 siblings, 0 replies; 23+ messages in thread From: Christoph Lameter @ 2007-09-25 23:25 UTC (permalink / raw) To: akpm; +Cc: linux-mm [-- Attachment #1: vcompound_zero_user_segment --] [-- Type: text/plain, Size: 26603 bytes --] Simplify page cache zeroing of segments of pages through 3 functions zero_user_segments(page, start1, end1, start2, end2) Zeros two segments of the page. It takes the position where to start and end the zeroing which avoids length calculations and makes code clearer. zero_user_segment(page, start, end) Same for a single segment. zero_user(page, start, length) Length variant for the case where we know the length. We remove the zero_user_page macro. Issues: 1. Its a macro. Inline functions are preferable. 2. The KM_USER0 macro is only defined for HIGHMEM. Having to treat this special case everywhere makes the code needlessly complex. The parameter for zeroing is always KM_USER0 except in one single case that we open code. Avoiding KM_USER0 makes a lot of code not having to be dealing with the special casing for HIGHMEM anymore. Dealing with kmap is only necessary for HIGHMEM configurations. In those configurations we use KM_USER0 like we do for a series of other functions defined in highmem.h. Since KM_USER0 is depends on HIGHMEM the existing zero_user_page function could not be a macro. zero_user_* functions introduced here can be be inline because that constant is not used when these functions are called. Also extract the flushing of the caches to be outside of the kmap. Signed-off-by: Christoph Lameter <clameter@sgi.com> --- fs/buffer.c | 47 +++++++++++++------------------------------ fs/cifs/inode.c | 2 - fs/direct-io.c | 4 +-- fs/ecryptfs/mmap.c | 7 ++---- fs/ext3/inode.c | 4 +-- fs/ext4/inode.c | 4 +-- fs/gfs2/bmap.c | 2 - fs/gfs2/ops_address.c | 2 - fs/libfs.c | 11 +++------- fs/mpage.c | 7 +----- fs/nfs/read.c | 10 ++++----- fs/nfs/write.c | 2 - fs/ntfs/aops.c | 18 +++++++++------- fs/ntfs/file.c | 32 +++++++++++++---------------- fs/ocfs2/aops.c | 6 ++--- fs/reiserfs/inode.c | 4 +-- fs/xfs/linux-2.6/xfs_lrw.c | 2 - include/linux/highmem.h | 49 ++++++++++++++++++++++++++++----------------- mm/filemap_xip.c | 2 - mm/truncate.c | 2 - 20 files changed, 103 insertions(+), 114 deletions(-) Index: linux-2.6.23-rc8-mm1/fs/buffer.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/buffer.c 2007-09-25 15:08:14.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/buffer.c 2007-09-25 15:14:40.000000000 -0700 @@ -1805,7 +1805,7 @@ void page_zero_new_buffers(struct page * start = max(from, block_start); size = min(to, block_end) - start; - zero_user_page(page, start, size, KM_USER0); + zero_user(page, start, size); set_buffer_uptodate(bh); } @@ -1868,19 +1868,10 @@ static int __block_prepare_write(struct mark_buffer_dirty(bh); continue; } - if (block_end > to || block_start < from) { - void *kaddr; - - kaddr = kmap_atomic(page, KM_USER0); - if (block_end > to) - memset(kaddr+to, 0, - block_end-to); - if (block_start < from) - memset(kaddr+block_start, - 0, from-block_start); - flush_dcache_page(page); - kunmap_atomic(kaddr, KM_USER0); - } + if (block_end > to || block_start < from) + zero_user_segments(page, + to, block_end, + block_start, from); continue; } } @@ -2111,8 +2102,7 @@ int block_read_full_page(struct page *pa SetPageError(page); } if (!buffer_mapped(bh)) { - zero_user_page(page, i * blocksize, blocksize, - KM_USER0); + zero_user(page, i * blocksize, blocksize); if (!err) set_buffer_uptodate(bh); continue; @@ -2225,7 +2215,7 @@ int cont_expand_zero(struct file *file, &page, &fsdata); if (err) goto out; - zero_user_page(page, zerofrom, len, KM_USER0); + zero_user(page, zerofrom, len); err = pagecache_write_end(file, mapping, curpos, len, len, page, fsdata); if (err < 0) @@ -2252,7 +2242,7 @@ int cont_expand_zero(struct file *file, &page, &fsdata); if (err) goto out; - zero_user_page(page, zerofrom, len, KM_USER0); + zero_user(page, zerofrom, len); err = pagecache_write_end(file, mapping, curpos, len, len, page, fsdata); if (err < 0) @@ -2400,7 +2390,6 @@ int nobh_prepare_write(struct page *page unsigned block_in_page; unsigned block_start, block_end; sector_t block_in_file; - char *kaddr; int nr_reads = 0; int ret = 0; int is_mapped_to_disk = 1; @@ -2454,13 +2443,8 @@ int nobh_prepare_write(struct page *page continue; } if (buffer_new(bh) || !buffer_mapped(bh)) { - kaddr = kmap_atomic(page, KM_USER0); - if (block_start < from) - memset(kaddr+block_start, 0, from-block_start); - if (block_end > to) - memset(kaddr + to, 0, block_end - to); - flush_dcache_page(page); - kunmap_atomic(kaddr, KM_USER0); + zero_user_segments(page, block_start, from, + to, block_end); continue; } if (buffer_uptodate(bh)) @@ -2525,7 +2509,7 @@ failed: if (buffer_new(bh)) { clear_buffer_new(bh); if (!buffer_uptodate(bh)) { - zero_user_page(page, block_start, bh->b_size, KM_USER0); + zero_user(page, block_start, bh->b_size); set_buffer_uptodate(bh); } mark_buffer_dirty(bh); @@ -2608,7 +2592,7 @@ int nobh_writepage(struct page *page, ge * the page size, the remaining memory is zeroed when mapped, and * writes to that region are not written out to the file." */ - zero_user_page(page, offset, PAGE_CACHE_SIZE - offset, KM_USER0); + zero_user_segment(page, offset, PAGE_CACHE_SIZE); out: ret = mpage_writepage(page, get_block, wbc); if (ret == -EAGAIN) @@ -2642,8 +2626,7 @@ int nobh_truncate_page(struct address_sp to = (offset + blocksize) & ~(blocksize - 1); ret = a_ops->prepare_write(NULL, page, offset, to); if (ret == 0) { - zero_user_page(page, offset, PAGE_CACHE_SIZE - offset, - KM_USER0); + zero_user_segment(page, offset, PAGE_CACHE_SIZE); /* * It would be more correct to call aops->commit_write() * here, but this is more efficient. @@ -2722,7 +2705,7 @@ int block_truncate_page(struct address_s goto unlock; } - zero_user_page(page, offset, length, KM_USER0); + zero_user(page, offset, length); mark_buffer_dirty(bh); err = 0; @@ -2768,7 +2751,7 @@ int block_write_full_page(struct page *p * the page size, the remaining memory is zeroed when mapped, and * writes to that region are not written out to the file." */ - zero_user_page(page, offset, PAGE_CACHE_SIZE - offset, KM_USER0); + zero_user_segment(page, offset, PAGE_CACHE_SIZE); return __block_write_full_page(inode, page, get_block, wbc); } Index: linux-2.6.23-rc8-mm1/fs/cifs/inode.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/cifs/inode.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/cifs/inode.c 2007-09-25 15:08:45.000000000 -0700 @@ -1361,7 +1361,7 @@ static int cifs_truncate_page(struct add if (!page) return -ENOMEM; - zero_user_page(page, offset, PAGE_CACHE_SIZE - offset, KM_USER0); + zero_user_segment(page, offset, PAGE_CACHE_SIZE); unlock_page(page); page_cache_release(page); return rc; Index: linux-2.6.23-rc8-mm1/fs/direct-io.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/direct-io.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/direct-io.c 2007-09-25 15:08:45.000000000 -0700 @@ -887,8 +887,8 @@ do_holes: page_cache_release(page); goto out; } - zero_user_page(page, block_in_page << blkbits, - 1 << blkbits, KM_USER0); + zero_user(page, block_in_page << blkbits, + 1 << blkbits); dio->block_in_file++; block_in_page++; goto next_block; Index: linux-2.6.23-rc8-mm1/fs/ecryptfs/mmap.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/ecryptfs/mmap.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/ecryptfs/mmap.c 2007-09-25 15:08:45.000000000 -0700 @@ -251,8 +251,7 @@ static int fill_zeros_to_end_of_page(str end_byte_in_page = i_size_read(inode) % PAGE_CACHE_SIZE; if (to > end_byte_in_page) end_byte_in_page = to; - zero_user_page(page, end_byte_in_page, - PAGE_CACHE_SIZE - end_byte_in_page, KM_USER0); + zero_user_segment(page, end_byte_in_page, PAGE_CACHE_SIZE); out: return 0; } @@ -284,7 +283,7 @@ static int ecryptfs_prepare_write(struct } } if (end_of_prev_pg_pos + 1 > i_size_read(page->mapping->host)) - zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); + zero_user(page, 0, PAGE_CACHE_SIZE); } out: return rc; Index: linux-2.6.23-rc8-mm1/fs/ext3/inode.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/ext3/inode.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/ext3/inode.c 2007-09-25 15:08:45.000000000 -0700 @@ -1845,7 +1845,7 @@ static int ext3_block_truncate_page(hand */ if (!page_has_buffers(page) && test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode) && PageUptodate(page)) { - zero_user_page(page, offset, length, KM_USER0); + zero_user(page, offset, length); set_page_dirty(page); goto unlock; } @@ -1898,7 +1898,7 @@ static int ext3_block_truncate_page(hand goto unlock; } - zero_user_page(page, offset, length, KM_USER0); + zero_user(page, offset, length); BUFFER_TRACE(bh, "zeroed end of block"); err = 0; Index: linux-2.6.23-rc8-mm1/fs/ext4/inode.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/ext4/inode.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/ext4/inode.c 2007-09-25 15:08:45.000000000 -0700 @@ -1873,7 +1873,7 @@ int ext4_block_truncate_page(handle_t *h */ if (!page_has_buffers(page) && test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode) && PageUptodate(page)) { - zero_user_page(page, offset, length, KM_USER0); + zero_user(page, offset, length); set_page_dirty(page); goto unlock; } @@ -1926,7 +1926,7 @@ int ext4_block_truncate_page(handle_t *h goto unlock; } - zero_user_page(page, offset, length, KM_USER0); + zero_user(page, offset, length); BUFFER_TRACE(bh, "zeroed end of block"); Index: linux-2.6.23-rc8-mm1/fs/gfs2/bmap.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/gfs2/bmap.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/gfs2/bmap.c 2007-09-25 15:08:45.000000000 -0700 @@ -934,7 +934,7 @@ static int gfs2_block_truncate_page(stru if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) gfs2_trans_add_bh(ip->i_gl, bh, 0); - zero_user_page(page, offset, length, KM_USER0); + zero_user(page, offset, length); unlock: unlock_page(page); Index: linux-2.6.23-rc8-mm1/fs/gfs2/ops_address.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/gfs2/ops_address.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/gfs2/ops_address.c 2007-09-25 15:08:45.000000000 -0700 @@ -209,7 +209,7 @@ static int stuffed_readpage(struct gfs2_ * so we need to supply one here. It doesn't happen often. */ if (unlikely(page->index)) { - zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); + zero_user(page, 0, PAGE_CACHE_SIZE); return 0; } Index: linux-2.6.23-rc8-mm1/fs/libfs.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/libfs.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/libfs.c 2007-09-25 15:08:45.000000000 -0700 @@ -341,13 +341,10 @@ int simple_prepare_write(struct file *fi unsigned from, unsigned to) { if (!PageUptodate(page)) { - if (to - from != PAGE_CACHE_SIZE) { - void *kaddr = kmap_atomic(page, KM_USER0); - memset(kaddr, 0, from); - memset(kaddr + to, 0, PAGE_CACHE_SIZE - to); - flush_dcache_page(page); - kunmap_atomic(kaddr, KM_USER0); - } + if (to - from != PAGE_CACHE_SIZE) + zero_user_segments(page, + 0, from, + to, PAGE_CACHE_SIZE); } return 0; } Index: linux-2.6.23-rc8-mm1/fs/mpage.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/mpage.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/mpage.c 2007-09-25 15:08:45.000000000 -0700 @@ -284,9 +284,7 @@ do_mpage_readpage(struct bio *bio, struc } if (first_hole != blocks_per_page) { - zero_user_page(page, first_hole << blkbits, - PAGE_CACHE_SIZE - (first_hole << blkbits), - KM_USER0); + zero_user_segment(page, first_hole << blkbits, PAGE_CACHE_SIZE); if (first_hole == 0) { SetPageUptodate(page); unlock_page(page); @@ -579,8 +577,7 @@ page_is_mapped: if (page->index > end_index || !offset) goto confused; - zero_user_page(page, offset, PAGE_CACHE_SIZE - offset, - KM_USER0); + zero_user_segment(page, offset, PAGE_CACHE_SIZE); } /* Index: linux-2.6.23-rc8-mm1/fs/nfs/read.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/nfs/read.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/nfs/read.c 2007-09-25 15:08:45.000000000 -0700 @@ -79,7 +79,7 @@ void nfs_readdata_release(void *data) static int nfs_return_empty_page(struct page *page) { - zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); + zero_user(page, 0, PAGE_CACHE_SIZE); SetPageUptodate(page); unlock_page(page); return 0; @@ -103,10 +103,10 @@ static void nfs_readpage_truncate_uninit pglen = PAGE_CACHE_SIZE - base; for (;;) { if (remainder <= pglen) { - zero_user_page(*pages, base, remainder, KM_USER0); + zero_user(*pages, base, remainder); break; } - zero_user_page(*pages, base, pglen, KM_USER0); + zero_user(*pages, base, pglen); pages++; remainder -= pglen; pglen = PAGE_CACHE_SIZE; @@ -130,7 +130,7 @@ static int nfs_readpage_async(struct nfs return PTR_ERR(new); } if (len < PAGE_CACHE_SIZE) - zero_user_page(page, len, PAGE_CACHE_SIZE - len, KM_USER0); + zero_user_segment(page, len, PAGE_CACHE_SIZE); nfs_list_add_request(new, &one_request); if (NFS_SERVER(inode)->rsize < PAGE_CACHE_SIZE) @@ -537,7 +537,7 @@ readpage_async_filler(void *data, struct goto out_error; if (len < PAGE_CACHE_SIZE) - zero_user_page(page, len, PAGE_CACHE_SIZE - len, KM_USER0); + zero_user_segment(page, len, PAGE_CACHE_SIZE); nfs_pageio_add_request(desc->pgio, new); return 0; out_error: Index: linux-2.6.23-rc8-mm1/fs/nfs/write.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/nfs/write.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/nfs/write.c 2007-09-25 15:08:45.000000000 -0700 @@ -175,7 +175,7 @@ static void nfs_mark_uptodate(struct pag if (count != nfs_page_length(page)) return; if (count != PAGE_CACHE_SIZE) - zero_user_page(page, count, PAGE_CACHE_SIZE - count, KM_USER0); + zero_user_segment(page, count, PAGE_CACHE_SIZE); SetPageUptodate(page); } Index: linux-2.6.23-rc8-mm1/fs/ntfs/aops.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/ntfs/aops.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/ntfs/aops.c 2007-09-25 15:08:45.000000000 -0700 @@ -87,13 +87,17 @@ static void ntfs_end_buffer_async_read(s /* Check for the current buffer head overflowing. */ if (unlikely(file_ofs + bh->b_size > init_size)) { int ofs; + void *kaddr; ofs = 0; if (file_ofs < init_size) ofs = init_size - file_ofs; local_irq_save(flags); - zero_user_page(page, bh_offset(bh) + ofs, - bh->b_size - ofs, KM_BIO_SRC_IRQ); + kaddr = kmap_atomic(page, KM_BIO_SRC_IRQ); + memset(kaddr + bh_offset(bh) + ofs, 0, + bh->b_size - ofs); + flush_dcache_page(page); + kunmap_atomic(kaddr, KM_BIO_SRC_IRQ); local_irq_restore(flags); } } else { @@ -334,7 +338,7 @@ handle_hole: bh->b_blocknr = -1UL; clear_buffer_mapped(bh); handle_zblock: - zero_user_page(page, i * blocksize, blocksize, KM_USER0); + zero_user(page, i * blocksize, blocksize); if (likely(!err)) set_buffer_uptodate(bh); } while (i++, iblock++, (bh = bh->b_this_page) != head); @@ -451,7 +455,7 @@ retry_readpage: * ok to ignore the compressed flag here. */ if (unlikely(page->index > 0)) { - zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); + zero_user(page, 0, PAGE_CACHE_SIZE); goto done; } if (!NInoAttr(ni)) @@ -780,8 +784,7 @@ lock_retry_remap: if (err == -ENOENT || lcn == LCN_ENOENT) { bh->b_blocknr = -1; clear_buffer_dirty(bh); - zero_user_page(page, bh_offset(bh), blocksize, - KM_USER0); + zero_user(page, bh_offset(bh), blocksize); set_buffer_uptodate(bh); err = 0; continue; @@ -1406,8 +1409,7 @@ retry_writepage: if (page->index >= (i_size >> PAGE_CACHE_SHIFT)) { /* The page straddles i_size. */ unsigned int ofs = i_size & ~PAGE_CACHE_MASK; - zero_user_page(page, ofs, PAGE_CACHE_SIZE - ofs, - KM_USER0); + zero_user_segment(page, ofs, PAGE_CACHE_SIZE); } /* Handle mst protected attributes. */ if (NInoMstProtected(ni)) Index: linux-2.6.23-rc8-mm1/fs/ntfs/file.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/ntfs/file.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/ntfs/file.c 2007-09-25 15:08:45.000000000 -0700 @@ -606,8 +606,8 @@ do_next_page: ntfs_submit_bh_for_read(bh); *wait_bh++ = bh; } else { - zero_user_page(page, bh_offset(bh), - blocksize, KM_USER0); + zero_user(page, bh_offset(bh), + blocksize); set_buffer_uptodate(bh); } } @@ -682,9 +682,8 @@ map_buffer_cached: ntfs_submit_bh_for_read(bh); *wait_bh++ = bh; } else { - zero_user_page(page, - bh_offset(bh), - blocksize, KM_USER0); + zero_user(page, bh_offset(bh), + blocksize); set_buffer_uptodate(bh); } } @@ -702,8 +701,8 @@ map_buffer_cached: */ if (bh_end <= pos || bh_pos >= end) { if (!buffer_uptodate(bh)) { - zero_user_page(page, bh_offset(bh), - blocksize, KM_USER0); + zero_user(page, bh_offset(bh), + blocksize); set_buffer_uptodate(bh); } mark_buffer_dirty(bh); @@ -742,8 +741,7 @@ map_buffer_cached: if (!buffer_uptodate(bh)) set_buffer_uptodate(bh); } else if (!buffer_uptodate(bh)) { - zero_user_page(page, bh_offset(bh), blocksize, - KM_USER0); + zero_user(page, bh_offset(bh), blocksize); set_buffer_uptodate(bh); } continue; @@ -867,8 +865,8 @@ rl_not_mapped_enoent: if (!buffer_uptodate(bh)) set_buffer_uptodate(bh); } else if (!buffer_uptodate(bh)) { - zero_user_page(page, bh_offset(bh), - blocksize, KM_USER0); + zero_user(page, bh_offset(bh), + blocksize); set_buffer_uptodate(bh); } continue; @@ -1127,8 +1125,8 @@ rl_not_mapped_enoent: if (likely(bh_pos < initialized_size)) ofs = initialized_size - bh_pos; - zero_user_page(page, bh_offset(bh) + ofs, - blocksize - ofs, KM_USER0); + zero_user_segment(page, bh_offset(bh) + ofs, + blocksize); } } else /* if (unlikely(!buffer_uptodate(bh))) */ err = -EIO; @@ -1268,8 +1266,8 @@ rl_not_mapped_enoent: if (PageUptodate(page)) set_buffer_uptodate(bh); else { - zero_user_page(page, bh_offset(bh), - blocksize, KM_USER0); + zero_user(page, bh_offset(bh), + blocksize); set_buffer_uptodate(bh); } } @@ -1329,7 +1327,7 @@ err_out: len = PAGE_CACHE_SIZE; if (len > bytes) len = bytes; - zero_user_page(*pages, 0, len, KM_USER0); + zero_user(*pages, 0, len); } goto out; } @@ -1450,7 +1448,7 @@ err_out: len = PAGE_CACHE_SIZE; if (len > bytes) len = bytes; - zero_user_page(*pages, 0, len, KM_USER0); + zero_user(*pages, 0, len); } goto out; } Index: linux-2.6.23-rc8-mm1/fs/ocfs2/aops.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/ocfs2/aops.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/ocfs2/aops.c 2007-09-25 15:08:45.000000000 -0700 @@ -299,7 +299,7 @@ static int ocfs2_readpage(struct file *f * XXX sys_readahead() seems to get that wrong? */ if (start >= i_size_read(inode)) { - zero_user_page(page, 0, PAGE_SIZE, KM_USER0); + zero_user(page, 0, PAGE_SIZE); SetPageUptodate(page); ret = 0; goto out_alloc; @@ -814,7 +814,7 @@ int ocfs2_map_page_blocks(struct page *p if (block_start >= to) break; - zero_user_page(page, block_start, bh->b_size, KM_USER0); + zero_user(page, block_start, bh->b_size); set_buffer_uptodate(bh); mark_buffer_dirty(bh); @@ -979,7 +979,7 @@ static void ocfs2_zero_new_buffers(struc start = max(from, block_start); end = min(to, block_end); - zero_user_page(page, start, end - start, KM_USER0); + zero_user_segment(page, start, end); set_buffer_uptodate(bh); } Index: linux-2.6.23-rc8-mm1/fs/reiserfs/inode.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/reiserfs/inode.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/reiserfs/inode.c 2007-09-25 15:08:45.000000000 -0700 @@ -2143,7 +2143,7 @@ int reiserfs_truncate_file(struct inode /* if we are not on a block boundary */ if (length) { length = blocksize - length; - zero_user_page(page, offset, length, KM_USER0); + zero_user(page, offset, length); if (buffer_mapped(bh) && bh->b_blocknr != 0) { mark_buffer_dirty(bh); } @@ -2367,7 +2367,7 @@ static int reiserfs_write_full_page(stru unlock_page(page); return 0; } - zero_user_page(page, last_offset, PAGE_CACHE_SIZE - last_offset, KM_USER0); + zero_user_segment(page, last_offset, PAGE_CACHE_SIZE); } bh = head; block = page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits); Index: linux-2.6.23-rc8-mm1/fs/xfs/linux-2.6/xfs_lrw.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/xfs/linux-2.6/xfs_lrw.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/xfs/linux-2.6/xfs_lrw.c 2007-09-25 15:08:45.000000000 -0700 @@ -156,7 +156,7 @@ xfs_iozero( if (status) break; - zero_user_page(page, offset, bytes, KM_USER0); + zero_user(page, offset, bytes); status = pagecache_write_end(NULL, mapping, pos, bytes, bytes, page, fsdata); Index: linux-2.6.23-rc8-mm1/include/linux/highmem.h =================================================================== --- linux-2.6.23-rc8-mm1.orig/include/linux/highmem.h 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/include/linux/highmem.h 2007-09-25 15:08:45.000000000 -0700 @@ -124,28 +124,41 @@ static inline void clear_highpage(struct kunmap_atomic(kaddr, KM_USER0); } -/* - * Same but also flushes aliased cache contents to RAM. - * - * This must be a macro because KM_USER0 and friends aren't defined if - * !CONFIG_HIGHMEM - */ -#define zero_user_page(page, offset, size, km_type) \ - do { \ - void *kaddr; \ - \ - BUG_ON((offset) + (size) > PAGE_SIZE); \ - \ - kaddr = kmap_atomic(page, km_type); \ - memset((char *)kaddr + (offset), 0, (size)); \ - flush_dcache_page(page); \ - kunmap_atomic(kaddr, (km_type)); \ - } while (0) +static inline void zero_user_segments(struct page *page, + unsigned start1, unsigned end1, + unsigned start2, unsigned end2) +{ + void *kaddr = kmap_atomic(page, KM_USER0); + + BUG_ON(end1 > PAGE_SIZE || + end2 > PAGE_SIZE); + + if (end1 > start1) + memset(kaddr + start1, 0, end1 - start1); + + if (end2 > start2) + memset(kaddr + start2, 0, end2 - start2); + + kunmap_atomic(kaddr, KM_USER0); + flush_dcache_page(page); +} + +static inline void zero_user_segment(struct page *page, + unsigned start, unsigned end) +{ + zero_user_segments(page, start, end, 0, 0); +} + +static inline void zero_user(struct page *page, + unsigned start, unsigned size) +{ + zero_user_segments(page, start, start + size, 0, 0); +} static inline void __deprecated memclear_highpage_flush(struct page *page, unsigned int offset, unsigned int size) { - zero_user_page(page, offset, size, KM_USER0); + zero_user(page, offset, size); } #ifndef __HAVE_ARCH_COPY_USER_HIGHPAGE Index: linux-2.6.23-rc8-mm1/mm/filemap_xip.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/mm/filemap_xip.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/mm/filemap_xip.c 2007-09-25 15:08:45.000000000 -0700 @@ -430,7 +430,7 @@ xip_truncate_page(struct address_space * else return PTR_ERR(page); } - zero_user_page(page, offset, length, KM_USER0); + zero_user(page, offset, length); return 0; } EXPORT_SYMBOL_GPL(xip_truncate_page); Index: linux-2.6.23-rc8-mm1/mm/truncate.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/mm/truncate.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/mm/truncate.c 2007-09-25 15:08:45.000000000 -0700 @@ -48,7 +48,7 @@ void do_invalidatepage(struct page *page static inline void truncate_partial_page(struct page *page, unsigned partial) { - zero_user_page(page, partial, PAGE_CACHE_SIZE - partial, KM_USER0); + zero_user_segment(page, partial, PAGE_CACHE_SIZE); if (PagePrivate(page)) do_invalidatepage(page, partial); } Index: linux-2.6.23-rc8-mm1/fs/ocfs2/alloc.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/ocfs2/alloc.c 2007-09-25 15:14:39.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/ocfs2/alloc.c 2007-09-25 15:14:46.000000000 -0700 @@ -5646,7 +5646,7 @@ static void ocfs2_map_and_dirty_page(str mlog_errno(ret); if (zero) - zero_user_page(page, from, to - from, KM_USER0); + zero_user_segment(page, from, to); /* * Need to set the buffers we zero'd into uptodate -- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* [patch 02/14] Reiser4 portion of zero_user cleanup patch 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter 2007-09-25 23:25 ` [patch 01/14] Pagecache zeroing: zero_user_segment, zero_user_segments and zero_user Christoph Lameter @ 2007-09-25 23:25 ` Christoph Lameter 2007-09-25 23:25 ` [patch 03/14] Move vmalloc_to_page() to mm/vmalloc Christoph Lameter ` (12 subsequent siblings) 14 siblings, 0 replies; 23+ messages in thread From: Christoph Lameter @ 2007-09-25 23:25 UTC (permalink / raw) To: akpm; +Cc: linux-mm [-- Attachment #1: zero_user_reiserfs --] [-- Type: text/plain, Size: 6009 bytes --] Reiser4 only exists in mm. So split this off. Signed-off-by: Christoph Lameter <clameter@sgi.com> --- fs/buffer.c | 2 +- fs/reiser4/plugin/file/cryptcompress.c | 8 +++----- fs/reiser4/plugin/file/file.c | 4 ++-- fs/reiser4/plugin/item/ctail.c | 8 ++++---- fs/reiser4/plugin/item/extent_file_ops.c | 4 ++-- fs/reiser4/plugin/item/tail.c | 3 +-- 6 files changed, 13 insertions(+), 16 deletions(-) Index: linux-2.6.23-rc8-mm1/fs/reiser4/plugin/file/cryptcompress.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/reiser4/plugin/file/cryptcompress.c 2007-09-25 15:12:22.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/reiser4/plugin/file/cryptcompress.c 2007-09-25 15:12:51.000000000 -0700 @@ -2056,7 +2056,7 @@ static int write_hole(struct inode *inod to_pg = min((typeof(pg_off))PAGE_CACHE_SIZE - pg_off, cl_count); lock_page(page); - zero_user_page(page, pg_off, to_pg, KM_USER0); + zero_user(page, pg_off, to_pg); SetPageUptodate(page); reiser4_set_page_dirty_internal(page); mark_page_accessed(page); @@ -2294,8 +2294,7 @@ static int read_some_cluster_pages(struc off = off_to_pgoff(win->off+win->count+win->delta); if (off) { lock_page(pg); - zero_user_page(pg, off, PAGE_CACHE_SIZE - off, - KM_USER0); + zero_user_segment(pg, off, PAGE_CACHE_SIZE); unlock_page(pg); } } @@ -2342,8 +2341,7 @@ static int read_some_cluster_pages(struc offset = off_to_pgoff(win->off + win->count + win->delta); - zero_user_page(pg, offset, PAGE_CACHE_SIZE - offset, - KM_USER0); + zero_user_segment(pg, offset, PAGE_CACHE_SIZE); unlock_page(pg); /* still not uptodate */ break; Index: linux-2.6.23-rc8-mm1/fs/reiser4/plugin/file/file.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/reiser4/plugin/file/file.c 2007-09-25 15:12:22.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/reiser4/plugin/file/file.c 2007-09-25 15:12:51.000000000 -0700 @@ -532,7 +532,7 @@ static int shorten_file(struct inode *in lock_page(page); assert("vs-1066", PageLocked(page)); - zero_user_page(page, padd_from, PAGE_CACHE_SIZE - padd_from, KM_USER0); + zero_user_segment(page, padd_from, PAGE_CACHE_SIZE); unlock_page(page); page_cache_release(page); /* the below does up(sbinfo->delete_mutex). Do not get confused */ @@ -1437,7 +1437,7 @@ int readpage_unix_file(struct file *file if (page->mapping->host->i_size <= page_offset(page)) { /* page is out of file */ - zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); + zero_user(page, 0, PAGE_CACHE_SIZE); SetPageUptodate(page); unlock_page(page); return 0; Index: linux-2.6.23-rc8-mm1/fs/reiser4/plugin/item/ctail.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/reiser4/plugin/item/ctail.c 2007-09-25 15:12:22.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/reiser4/plugin/item/ctail.c 2007-09-25 15:12:51.000000000 -0700 @@ -638,7 +638,7 @@ int do_readpage_ctail(struct inode * ino goto exit; to_page = pbytes(page_index(page), inode); if (to_page == 0) { - zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); + zero_user(page, 0, PAGE_CACHE_SIZE); SetPageUptodate(page); goto exit; } @@ -655,7 +655,7 @@ int do_readpage_ctail(struct inode * ino /* refresh bytes */ to_page = pbytes(page_index(page), inode); if (to_page == 0) { - zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); + zero_user(page, 0, PAGE_CACHE_SIZE); SetPageUptodate(page); goto exit; } @@ -678,7 +678,7 @@ int do_readpage_ctail(struct inode * ino */ case FAKE_DISK_CLUSTER: /* fill the page by zeroes */ - zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); + zero_user(page, 0, PAGE_CACHE_SIZE); SetPageUptodate(page); break; case PREP_DISK_CLUSTER: @@ -788,7 +788,7 @@ static int ctail_readpages_filler(void * return 0; } if (pbytes(page_index(page), inode) == 0) { - zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); + zero_user(page, 0, PAGE_CACHE_SIZE); SetPageUptodate(page); unlock_page(page); return 0; Index: linux-2.6.23-rc8-mm1/fs/reiser4/plugin/item/extent_file_ops.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/reiser4/plugin/item/extent_file_ops.c 2007-09-25 15:12:22.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/reiser4/plugin/item/extent_file_ops.c 2007-09-25 15:12:51.000000000 -0700 @@ -1136,7 +1136,7 @@ int reiser4_do_readpage_extent(reiser4_e */ j = jfind(mapping, index); if (j == NULL) { - zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); + zero_user(page, 0, PAGE_CACHE_SIZE); SetPageUptodate(page); unlock_page(page); return 0; @@ -1151,7 +1151,7 @@ int reiser4_do_readpage_extent(reiser4_e block = *jnode_get_io_block(j); spin_unlock_jnode(j); if (block == 0) { - zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); + zero_user(page, 0, PAGE_CACHE_SIZE); SetPageUptodate(page); unlock_page(page); jput(j); Index: linux-2.6.23-rc8-mm1/fs/reiser4/plugin/item/tail.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/reiser4/plugin/item/tail.c 2007-09-25 15:12:22.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/reiser4/plugin/item/tail.c 2007-09-25 15:12:51.000000000 -0700 @@ -392,8 +392,7 @@ static int do_readpage_tail(uf_coord_t * done: if (mapped != PAGE_CACHE_SIZE) - zero_user_page(page, mapped, PAGE_CACHE_SIZE - mapped, - KM_USER0); + zero_user_segment(page, mapped, PAGE_CACHE_SIZE); SetPageUptodate(page); out_unlock_page: unlock_page(page); -- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* [patch 03/14] Move vmalloc_to_page() to mm/vmalloc. 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter 2007-09-25 23:25 ` [patch 01/14] Pagecache zeroing: zero_user_segment, zero_user_segments and zero_user Christoph Lameter 2007-09-25 23:25 ` [patch 02/14] Reiser4 portion of zero_user cleanup patch Christoph Lameter @ 2007-09-25 23:25 ` Christoph Lameter 2007-09-25 23:25 ` [patch 04/14] vmalloc: add const to void ..tmp_kallsyms1.o.cmd ..tmp_kallsyms2.o.cmd ..tmp_vmlinux1.cmd ..tmp_vmlinux2.cmd .cf .cf1 .cf2 .cf3 .cfnet .config .config.old .gitignore .mailmap .missing-syscalls.d .pc .tmp_System.map .tmp_kallsyms1.S .tmp_kallsyms1.o .tmp_kallsyms2.S .tmp_kallsyms2.o .tmp_versions .tmp_vmlinux1 .tmp_vmlinux2 .version .vmlinux.cmd .vmlinux.o.cmd COPYING CREDITS Documentation Kbuild MAINTAINERS Makefile Module.symvers README REPORTING-BUGS System.map arch b block crypto drivers fs include init ipc kernel lib linux-2.6.23-rc8-mm1.tar.gz mips mm net patches scripts security sound tar-install test test_out usr vmlinux vmlinux.gz vmlinux.o vmlinux.sym xx parameters Christoph Lameter ` (11 subsequent siblings) 14 siblings, 0 replies; 23+ messages in thread From: Christoph Lameter @ 2007-09-25 23:25 UTC (permalink / raw) To: akpm; +Cc: linux-mm [-- Attachment #1: vcompound_move_vmalloc_to_page --] [-- Type: text/plain, Size: 4686 bytes --] We already have page table manipulation for vmalloc in vmalloc.c. Move the vmalloc_to_page() function there as well. Move the definitions for vmalloc related functions in mm.h to a newly created section. A better place would be vmalloc.h but mm.h is basic and may depend on these functions. An alternative would be to include vmalloc.h in mm.h (like done for vmstat.h). Signed-off-by: Christoph Lameter <clameter@sgi.com> --- include/linux/mm.h | 5 +++-- mm/memory.c | 40 ---------------------------------------- mm/vmalloc.c | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 42 deletions(-) Index: linux-2.6.23-rc8-mm1/mm/memory.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/mm/memory.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/mm/memory.c 2007-09-25 15:14:56.000000000 -0700 @@ -2651,46 +2651,6 @@ int make_pages_present(unsigned long add return ret == len ? 0 : -1; } -/* - * Map a vmalloc()-space virtual address to the physical page. - */ -struct page * vmalloc_to_page(void * vmalloc_addr) -{ - unsigned long addr = (unsigned long) vmalloc_addr; - struct page *page = NULL; - pgd_t *pgd = pgd_offset_k(addr); - pud_t *pud; - pmd_t *pmd; - pte_t *ptep, pte; - - if (!pgd_none(*pgd)) { - pud = pud_offset(pgd, addr); - if (!pud_none(*pud)) { - pmd = pmd_offset(pud, addr); - if (!pmd_none(*pmd)) { - ptep = pte_offset_map(pmd, addr); - pte = *ptep; - if (pte_present(pte)) - page = pte_page(pte); - pte_unmap(ptep); - } - } - } - return page; -} - -EXPORT_SYMBOL(vmalloc_to_page); - -/* - * Map a vmalloc()-space virtual address to the physical page frame number. - */ -unsigned long vmalloc_to_pfn(void * vmalloc_addr) -{ - return page_to_pfn(vmalloc_to_page(vmalloc_addr)); -} - -EXPORT_SYMBOL(vmalloc_to_pfn); - #if !defined(__HAVE_ARCH_GATE_AREA) #if defined(AT_SYSINFO_EHDR) Index: linux-2.6.23-rc8-mm1/mm/vmalloc.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/mm/vmalloc.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/mm/vmalloc.c 2007-09-25 15:14:56.000000000 -0700 @@ -166,6 +166,44 @@ int map_vm_area(struct vm_struct *area, } EXPORT_SYMBOL_GPL(map_vm_area); +/* + * Map a vmalloc()-space virtual address to the physical page. + */ +struct page *vmalloc_to_page(void *vmalloc_addr) +{ + unsigned long addr = (unsigned long) vmalloc_addr; + struct page *page = NULL; + pgd_t *pgd = pgd_offset_k(addr); + pud_t *pud; + pmd_t *pmd; + pte_t *ptep, pte; + + if (!pgd_none(*pgd)) { + pud = pud_offset(pgd, addr); + if (!pud_none(*pud)) { + pmd = pmd_offset(pud, addr); + if (!pmd_none(*pmd)) { + ptep = pte_offset_map(pmd, addr); + pte = *ptep; + if (pte_present(pte)) + page = pte_page(pte); + pte_unmap(ptep); + } + } + } + return page; +} +EXPORT_SYMBOL(vmalloc_to_page); + +/* + * Map a vmalloc()-space virtual address to the physical page frame number. + */ +unsigned long vmalloc_to_pfn(void *vmalloc_addr) +{ + return page_to_pfn(vmalloc_to_page(vmalloc_addr)); +} +EXPORT_SYMBOL(vmalloc_to_pfn); + static struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags, unsigned long start, unsigned long end, int node, gfp_t gfp_mask) Index: linux-2.6.23-rc8-mm1/include/linux/mm.h =================================================================== --- linux-2.6.23-rc8-mm1.orig/include/linux/mm.h 2007-09-25 15:08:14.000000000 -0700 +++ linux-2.6.23-rc8-mm1/include/linux/mm.h 2007-09-25 15:16:32.000000000 -0700 @@ -231,6 +231,10 @@ static inline int get_page_unless_zero(s return atomic_inc_not_zero(&page->_count); } +/* Support for virtually mapped pages */ +struct page *vmalloc_to_page(void *addr); +unsigned long vmalloc_to_pfn(void *addr); + static inline struct page *compound_head(struct page *page) { if (unlikely(PageTail(page))) @@ -1086,8 +1090,6 @@ static inline unsigned long vma_pages(st pgprot_t vm_get_page_prot(unsigned long vm_flags); struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr); -struct page *vmalloc_to_page(void *addr); -unsigned long vmalloc_to_pfn(void *addr); int remap_pfn_range(struct vm_area_struct *, unsigned long addr, unsigned long pfn, unsigned long size, pgprot_t); int vm_insert_page(struct vm_area_struct *, unsigned long addr, struct page *); -- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* [patch 04/14] vmalloc: add const to void ..tmp_kallsyms1.o.cmd ..tmp_kallsyms2.o.cmd ..tmp_vmlinux1.cmd ..tmp_vmlinux2.cmd .cf .cf1 .cf2 .cf3 .cfnet .config .config.old .gitignore .mailmap .missing-syscalls.d .pc .tmp_System.map .tmp_kallsyms1.S .tmp_kallsyms1.o .tmp_kallsyms2.S .tmp_kallsyms2.o .tmp_versions .tmp_vmlinux1 .tmp_vmlinux2 .version .vmlinux.cmd .vmlinux.o.cmd COPYING CREDITS Documentation Kbuild MAINTAINERS Makefile Module.symvers README REPORTING-BUGS System.map arch b block crypto drivers fs include init ipc kernel lib linux-2.6.23-rc8-mm1.tar.gz mips mm net patches scripts security sound tar-install test test_out usr vmlinux vmlinux.gz vmlinux.o vmlinux.sym xx parameters. 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter ` (2 preceding siblings ...) 2007-09-25 23:25 ` [patch 03/14] Move vmalloc_to_page() to mm/vmalloc Christoph Lameter @ 2007-09-25 23:25 ` Christoph Lameter 2007-09-25 23:25 ` [patch 05/14] i386: Resolve dependency of asm-i386/pgtable.h on highmem.h Christoph Lameter ` (10 subsequent siblings) 14 siblings, 0 replies; 23+ messages in thread From: Christoph Lameter @ 2007-09-25 23:25 UTC (permalink / raw) To: akpm; +Cc: linux-mm [-- Attachment #1: vcompound_vmalloc_const --] [-- Type: text/plain, Size: 4797 bytes --] Make vmalloc functions work the same way as kfree() and friends that take a const void * argument. Signed-off-by: Christoph Lameter <clameter@sgi.com> --- include/linux/mm.h | 4 ++-- include/linux/vmalloc.h | 6 +++--- mm/vmalloc.c | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) Index: linux-2.6.23-rc8-mm1/mm/vmalloc.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/mm/vmalloc.c 2007-09-25 15:14:56.000000000 -0700 +++ linux-2.6.23-rc8-mm1/mm/vmalloc.c 2007-09-25 15:16:38.000000000 -0700 @@ -169,7 +169,7 @@ EXPORT_SYMBOL_GPL(map_vm_area); /* * Map a vmalloc()-space virtual address to the physical page. */ -struct page *vmalloc_to_page(void *vmalloc_addr) +struct page *vmalloc_to_page(const void *vmalloc_addr) { unsigned long addr = (unsigned long) vmalloc_addr; struct page *page = NULL; @@ -198,7 +198,7 @@ EXPORT_SYMBOL(vmalloc_to_page); /* * Map a vmalloc()-space virtual address to the physical page frame number. */ -unsigned long vmalloc_to_pfn(void *vmalloc_addr) +unsigned long vmalloc_to_pfn(const void *vmalloc_addr) { return page_to_pfn(vmalloc_to_page(vmalloc_addr)); } @@ -306,7 +306,7 @@ struct vm_struct *get_vm_area_node(unsig } /* Caller must hold vmlist_lock */ -static struct vm_struct *__find_vm_area(void *addr) +static struct vm_struct *__find_vm_area(const void *addr) { struct vm_struct *tmp; @@ -319,7 +319,7 @@ static struct vm_struct *__find_vm_area( } /* Caller must hold vmlist_lock */ -static struct vm_struct *__remove_vm_area(void *addr) +static struct vm_struct *__remove_vm_area(const void *addr) { struct vm_struct **p, *tmp; @@ -348,7 +348,7 @@ found: * This function returns the found VM area, but using it is NOT safe * on SMP machines, except for its size or flags. */ -struct vm_struct *remove_vm_area(void *addr) +struct vm_struct *remove_vm_area(const void *addr) { struct vm_struct *v; write_lock(&vmlist_lock); @@ -357,7 +357,7 @@ struct vm_struct *remove_vm_area(void *a return v; } -static void __vunmap(void *addr, int deallocate_pages) +static void __vunmap(const void *addr, int deallocate_pages) { struct vm_struct *area; @@ -408,7 +408,7 @@ static void __vunmap(void *addr, int dea * * Must not be called in interrupt context. */ -void vfree(void *addr) +void vfree(const void *addr) { BUG_ON(in_interrupt()); __vunmap(addr, 1); @@ -424,7 +424,7 @@ EXPORT_SYMBOL(vfree); * * Must not be called in interrupt context. */ -void vunmap(void *addr) +void vunmap(const void *addr) { BUG_ON(in_interrupt()); __vunmap(addr, 0); Index: linux-2.6.23-rc8-mm1/include/linux/vmalloc.h =================================================================== --- linux-2.6.23-rc8-mm1.orig/include/linux/vmalloc.h 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/include/linux/vmalloc.h 2007-09-25 15:16:38.000000000 -0700 @@ -45,11 +45,11 @@ extern void *vmalloc_32_user(unsigned lo extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot); extern void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot); -extern void vfree(void *addr); +extern void vfree(const void *addr); extern void *vmap(struct page **pages, unsigned int count, unsigned long flags, pgprot_t prot); -extern void vunmap(void *addr); +extern void vunmap(const void *addr); extern int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, unsigned long pgoff); @@ -71,7 +71,7 @@ extern struct vm_struct *__get_vm_area(u extern struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags, int node, gfp_t gfp_mask); -extern struct vm_struct *remove_vm_area(void *addr); +extern struct vm_struct *remove_vm_area(const void *addr); extern int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages); Index: linux-2.6.23-rc8-mm1/include/linux/mm.h =================================================================== --- linux-2.6.23-rc8-mm1.orig/include/linux/mm.h 2007-09-25 15:16:32.000000000 -0700 +++ linux-2.6.23-rc8-mm1/include/linux/mm.h 2007-09-25 15:16:53.000000000 -0700 @@ -232,8 +232,8 @@ static inline int get_page_unless_zero(s } /* Support for virtually mapped pages */ -struct page *vmalloc_to_page(void *addr); -unsigned long vmalloc_to_pfn(void *addr); +struct page *vmalloc_to_page(const void *addr); +unsigned long vmalloc_to_pfn(const void *addr); static inline struct page *compound_head(struct page *page) { -- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* [patch 05/14] i386: Resolve dependency of asm-i386/pgtable.h on highmem.h 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter ` (3 preceding siblings ...) 2007-09-25 23:25 ` [patch 04/14] vmalloc: add const to void ..tmp_kallsyms1.o.cmd ..tmp_kallsyms2.o.cmd ..tmp_vmlinux1.cmd ..tmp_vmlinux2.cmd .cf .cf1 .cf2 .cf3 .cfnet .config .config.old .gitignore .mailmap .missing-syscalls.d .pc .tmp_System.map .tmp_kallsyms1.S .tmp_kallsyms1.o .tmp_kallsyms2.S .tmp_kallsyms2.o .tmp_versions .tmp_vmlinux1 .tmp_vmlinux2 .version .vmlinux.cmd .vmlinux.o.cmd COPYING CREDITS Documentation Kbuild MAINTAINERS Makefile Module.symvers README REPORTING-BUGS System.map arch b block crypto drivers fs include init ipc kernel lib linux-2.6.23-rc8-mm1.tar.gz mips mm net patches scripts security sound tar-install test test_out usr vmlinux vmlinux.gz vmlinux.o vmlinux.sym xx parameters Christoph Lameter @ 2007-09-25 23:25 ` Christoph Lameter 2007-09-25 23:25 ` [patch 06/14] is_vmalloc_addr(): Check if an address is within the vmalloc boundaries Christoph Lameter ` (9 subsequent siblings) 14 siblings, 0 replies; 23+ messages in thread From: Christoph Lameter @ 2007-09-25 23:25 UTC (permalink / raw) To: akpm; +Cc: linux-mm [-- Attachment #1: vcompound_fix_i386_pgtable_mess --] [-- Type: text/plain, Size: 2321 bytes --] pgtable.h does not include highmem.h but uses various constants from highmem.h. We cannot include highmem.h because highmem.h will in turn include many other include files that also depend on pgtable.h So move the definitions from highmem.h into pgtable.h. Signed-off-by: Christoph Lameter <clameter@sgi.com> --- include/asm-i386/highmem.h | 6 ------ include/asm-i386/pgtable.h | 8 ++++++++ 2 files changed, 8 insertions(+), 6 deletions(-) Index: linux-2.6.23-rc8-mm1/include/asm-i386/highmem.h =================================================================== --- linux-2.6.23-rc8-mm1.orig/include/asm-i386/highmem.h 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/include/asm-i386/highmem.h 2007-09-25 15:17:31.000000000 -0700 @@ -38,11 +38,6 @@ extern pte_t *pkmap_page_table; * easily, subsequent pte tables have to be allocated in one physical * chunk of RAM. */ -#ifdef CONFIG_X86_PAE -#define LAST_PKMAP 512 -#else -#define LAST_PKMAP 1024 -#endif /* * Ordering is: * @@ -58,7 +53,6 @@ extern pte_t *pkmap_page_table; * VMALLOC_START * high_memory */ -#define PKMAP_BASE ( (FIXADDR_BOOT_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK ) #define LAST_PKMAP_MASK (LAST_PKMAP-1) #define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT) #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) Index: linux-2.6.23-rc8-mm1/include/asm-i386/pgtable.h =================================================================== --- linux-2.6.23-rc8-mm1.orig/include/asm-i386/pgtable.h 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/include/asm-i386/pgtable.h 2007-09-25 15:17:31.000000000 -0700 @@ -78,6 +78,14 @@ void paging_init(void); #define VMALLOC_OFFSET (8*1024*1024) #define VMALLOC_START (((unsigned long) high_memory + \ 2*VMALLOC_OFFSET-1) & ~(VMALLOC_OFFSET-1)) +#ifdef CONFIG_X86_PAE +#define LAST_PKMAP 512 +#else +#define LAST_PKMAP 1024 +#endif + +#define PKMAP_BASE ( (FIXADDR_BOOT_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK ) + #ifdef CONFIG_HIGHMEM # define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE) #else -- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* [patch 06/14] is_vmalloc_addr(): Check if an address is within the vmalloc boundaries 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter ` (4 preceding siblings ...) 2007-09-25 23:25 ` [patch 05/14] i386: Resolve dependency of asm-i386/pgtable.h on highmem.h Christoph Lameter @ 2007-09-25 23:25 ` Christoph Lameter 2007-09-25 23:25 ` [patch 07/14] vmalloc: Clean up page array indexing Christoph Lameter ` (8 subsequent siblings) 14 siblings, 0 replies; 23+ messages in thread From: Christoph Lameter @ 2007-09-25 23:25 UTC (permalink / raw) To: akpm; +Cc: linux-mm [-- Attachment #1: vcompound_is_vmalloc_addr --] [-- Type: text/plain, Size: 5371 bytes --] Checking if an address is a vmalloc address is done in a couple of places. Define a common version in mm.h and replace the other checks. Again the include structures suck. The definition of VMALLOC_START and VMALLOC_END is not available in vmalloc.h since highmem.c cannot be included there. Signed-off-by: Christoph Lameter <clameter@sgi.com> --- drivers/net/cxgb3/cxgb3_offload.c | 4 +--- fs/ntfs/malloc.h | 3 +-- fs/proc/kcore.c | 2 +- fs/xfs/linux-2.6/kmem.c | 3 +-- fs/xfs/linux-2.6/xfs_buf.c | 3 +-- include/linux/mm.h | 8 ++++++++ mm/sparse.c | 10 +--------- 7 files changed, 14 insertions(+), 19 deletions(-) Index: linux-2.6.23-rc8-mm1/include/linux/mm.h =================================================================== --- linux-2.6.23-rc8-mm1.orig/include/linux/mm.h 2007-09-25 15:16:53.000000000 -0700 +++ linux-2.6.23-rc8-mm1/include/linux/mm.h 2007-09-25 15:19:26.000000000 -0700 @@ -235,6 +235,14 @@ static inline int get_page_unless_zero(s struct page *vmalloc_to_page(const void *addr); unsigned long vmalloc_to_pfn(const void *addr); +/* Determine if an address is within the vmalloc range */ +static inline int is_vmalloc_addr(const void *x) +{ + unsigned long addr = (unsigned long)x; + + return addr >= VMALLOC_START && addr < VMALLOC_END; +} + static inline struct page *compound_head(struct page *page) { if (unlikely(PageTail(page))) Index: linux-2.6.23-rc8-mm1/mm/sparse.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/mm/sparse.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/mm/sparse.c 2007-09-25 15:19:26.000000000 -0700 @@ -362,17 +362,9 @@ static inline struct page *kmalloc_secti return __kmalloc_section_memmap(nr_pages); } -static int vaddr_in_vmalloc_area(void *addr) -{ - if (addr >= (void *)VMALLOC_START && - addr < (void *)VMALLOC_END) - return 1; - return 0; -} - static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages) { - if (vaddr_in_vmalloc_area(memmap)) + if (is_vmalloc_addr(memmap)) vfree(memmap); else free_pages((unsigned long)memmap, Index: linux-2.6.23-rc8-mm1/drivers/net/cxgb3/cxgb3_offload.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/drivers/net/cxgb3/cxgb3_offload.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/drivers/net/cxgb3/cxgb3_offload.c 2007-09-25 15:19:26.000000000 -0700 @@ -1060,9 +1060,7 @@ void *cxgb_alloc_mem(unsigned long size) */ void cxgb_free_mem(void *addr) { - unsigned long p = (unsigned long)addr; - - if (p >= VMALLOC_START && p < VMALLOC_END) + if (is_vmalloc_addr(addr)) vfree(addr); else kfree(addr); Index: linux-2.6.23-rc8-mm1/fs/ntfs/malloc.h =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/ntfs/malloc.h 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/ntfs/malloc.h 2007-09-25 15:19:26.000000000 -0700 @@ -85,8 +85,7 @@ static inline void *ntfs_malloc_nofs_nof static inline void ntfs_free(void *addr) { - if (likely(((unsigned long)addr < VMALLOC_START) || - ((unsigned long)addr >= VMALLOC_END ))) { + if (!is_vmalloc_addr(addr)) { kfree(addr); /* free_page((unsigned long)addr); */ return; Index: linux-2.6.23-rc8-mm1/fs/proc/kcore.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/proc/kcore.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/proc/kcore.c 2007-09-25 15:19:26.000000000 -0700 @@ -325,7 +325,7 @@ read_kcore(struct file *file, char __use if (m == NULL) { if (clear_user(buffer, tsz)) return -EFAULT; - } else if ((start >= VMALLOC_START) && (start < VMALLOC_END)) { + } else if (is_vmalloc_addr((void *)start)) { char * elf_buf; struct vm_struct *m; unsigned long curstart = start; Index: linux-2.6.23-rc8-mm1/fs/xfs/linux-2.6/kmem.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/xfs/linux-2.6/kmem.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/xfs/linux-2.6/kmem.c 2007-09-25 15:19:26.000000000 -0700 @@ -92,8 +92,7 @@ kmem_zalloc_greedy(size_t *size, size_t void kmem_free(void *ptr, size_t size) { - if (((unsigned long)ptr < VMALLOC_START) || - ((unsigned long)ptr >= VMALLOC_END)) { + if (!is_vmalloc_addr(ptr)) { kfree(ptr); } else { vfree(ptr); Index: linux-2.6.23-rc8-mm1/fs/xfs/linux-2.6/xfs_buf.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/xfs/linux-2.6/xfs_buf.c 2007-09-25 15:08:13.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/xfs/linux-2.6/xfs_buf.c 2007-09-25 15:19:26.000000000 -0700 @@ -696,8 +696,7 @@ static inline struct page * mem_to_page( void *addr) { - if (((unsigned long)addr < VMALLOC_START) || - ((unsigned long)addr >= VMALLOC_END)) { + if ((!is_vmalloc_addr(addr))) { return virt_to_page(addr); } else { return vmalloc_to_page(addr); -- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* [patch 07/14] vmalloc: Clean up page array indexing 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter ` (5 preceding siblings ...) 2007-09-25 23:25 ` [patch 06/14] is_vmalloc_addr(): Check if an address is within the vmalloc boundaries Christoph Lameter @ 2007-09-25 23:25 ` Christoph Lameter 2007-09-25 23:25 ` [patch 08/14] vunmap: return page array passed on vmap() Christoph Lameter ` (7 subsequent siblings) 14 siblings, 0 replies; 23+ messages in thread From: Christoph Lameter @ 2007-09-25 23:25 UTC (permalink / raw) To: akpm; +Cc: linux-mm [-- Attachment #1: vcompound_array_indexes --] [-- Type: text/plain, Size: 1684 bytes --] The page array is repeatedly indexed both in vunmap and vmalloc_area_node(). Add a temporary variable to make it easier to read (and easier to patch later). Signed-off-by: Christoph Lameter <clameter@sgi.com> --- mm/vmalloc.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) Index: linux-2.6.23-rc8-mm1/mm/vmalloc.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/mm/vmalloc.c 2007-09-25 15:16:38.000000000 -0700 +++ linux-2.6.23-rc8-mm1/mm/vmalloc.c 2007-09-25 15:21:29.000000000 -0700 @@ -384,8 +384,10 @@ static void __vunmap(const void *addr, i int i; for (i = 0; i < area->nr_pages; i++) { - BUG_ON(!area->pages[i]); - __free_page(area->pages[i]); + struct page *page = area->pages[i]; + + BUG_ON(!page); + __free_page(page); } if (area->flags & VM_VPAGES) @@ -489,15 +491,19 @@ void *__vmalloc_area_node(struct vm_stru } for (i = 0; i < area->nr_pages; i++) { + struct page *page; + if (node < 0) - area->pages[i] = alloc_page(gfp_mask); + page = alloc_page(gfp_mask); else - area->pages[i] = alloc_pages_node(node, gfp_mask, 0); - if (unlikely(!area->pages[i])) { + page = alloc_pages_node(node, gfp_mask, 0); + + if (unlikely(!page)) { /* Successfully allocated i pages, free them in __vunmap() */ area->nr_pages = i; goto fail; } + area->pages[i] = page; } if (map_vm_area(area, prot, &pages)) -- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* [patch 08/14] vunmap: return page array passed on vmap() 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter ` (6 preceding siblings ...) 2007-09-25 23:25 ` [patch 07/14] vmalloc: Clean up page array indexing Christoph Lameter @ 2007-09-25 23:25 ` Christoph Lameter 2007-09-25 23:25 ` [patch 09/14] SLUB: Move count_partial() Christoph Lameter ` (6 subsequent siblings) 14 siblings, 0 replies; 23+ messages in thread From: Christoph Lameter @ 2007-09-25 23:25 UTC (permalink / raw) To: akpm; +Cc: linux-mm [-- Attachment #1: vcompound_vunmap_returns_pages --] [-- Type: text/plain, Size: 4607 bytes --] Make vunmap return the page array that was used at vmap. This is useful if one has no structures to track the page array but simply stores the virtual address somewhere. The disposition of the page array can be decided upon after vunmap. vfree() may now also be used instead of vunmap which will release the page array after vunmap'ping it. As noted by Kamezawa: The same subsystem that provides the page array to vmap must must use its own method to dispose of the page array. If vfree() is called to free the page array passed to vmap() [We currently do not do that] then the page array must either be 1. Allocated via the slab allocator 2. Allocated via vmalloc but then VM_VPAGES must have been passed at vunmap to specify that a vfree is needed. RFC->v1: - Add comment explaining how to use vfree() to dispose of the page array passed on vmap(). Signed-off-by: Christoph Lameter <clameter@sgi.com> --- include/linux/vmalloc.h | 2 +- mm/vmalloc.c | 33 +++++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 11 deletions(-) Index: linux-2.6.23-rc8-mm1/include/linux/vmalloc.h =================================================================== --- linux-2.6.23-rc8-mm1.orig/include/linux/vmalloc.h 2007-09-25 15:02:59.000000000 -0700 +++ linux-2.6.23-rc8-mm1/include/linux/vmalloc.h 2007-09-25 15:03:06.000000000 -0700 @@ -49,7 +49,7 @@ extern void vfree(const void *addr); extern void *vmap(struct page **pages, unsigned int count, unsigned long flags, pgprot_t prot); -extern void vunmap(const void *addr); +extern struct page **vunmap(const void *addr); extern int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, unsigned long pgoff); Index: linux-2.6.23-rc8-mm1/mm/vmalloc.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/mm/vmalloc.c 2007-09-25 15:03:05.000000000 -0700 +++ linux-2.6.23-rc8-mm1/mm/vmalloc.c 2007-09-25 15:03:06.000000000 -0700 @@ -357,17 +357,18 @@ struct vm_struct *remove_vm_area(const v return v; } -static void __vunmap(const void *addr, int deallocate_pages) +static struct page **__vunmap(const void *addr, int deallocate_pages) { struct vm_struct *area; + struct page **pages; if (!addr) - return; + return NULL; if ((PAGE_SIZE-1) & (unsigned long)addr) { printk(KERN_ERR "Trying to vfree() bad address (%p)\n", addr); WARN_ON(1); - return; + return NULL; } area = remove_vm_area(addr); @@ -375,29 +376,30 @@ static void __vunmap(const void *addr, i printk(KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n", addr); WARN_ON(1); - return; + return NULL; } + pages = area->pages; debug_check_no_locks_freed(addr, area->size); if (deallocate_pages) { int i; for (i = 0; i < area->nr_pages; i++) { - struct page *page = area->pages[i]; + struct page *page = pages[i]; BUG_ON(!page); __free_page(page); } if (area->flags & VM_VPAGES) - vfree(area->pages); + vfree(pages); else - kfree(area->pages); + kfree(pages); } kfree(area); - return; + return pages; } /** @@ -425,11 +427,13 @@ EXPORT_SYMBOL(vfree); * which was created from the page array passed to vmap(). * * Must not be called in interrupt context. + * + * Returns a pointer to the array of pointers to page structs */ -void vunmap(const void *addr) +struct page **vunmap(const void *addr) { BUG_ON(in_interrupt()); - __vunmap(addr, 0); + return __vunmap(addr, 0); } EXPORT_SYMBOL(vunmap); @@ -442,6 +446,13 @@ EXPORT_SYMBOL(vunmap); * * Maps @count pages from @pages into contiguous kernel virtual * space. + * + * The page array may be freed via vfree() with the virtual address + * returned from vmap. In that case the page array must be allocated via + * the slab allocator. If the page array was allocated via + * vmalloc then VM_VPAGES must be specified in the flags. There is + * no support for vfree() freeing pages allocated via the + * page allocator. */ void *vmap(struct page **pages, unsigned int count, unsigned long flags, pgprot_t prot) @@ -454,6 +465,8 @@ void *vmap(struct page **pages, unsigned area = get_vm_area((count << PAGE_SHIFT), flags); if (!area) return NULL; + area->pages = pages; + area->nr_pages = count; if (map_vm_area(area, prot, &pages)) { vunmap(area->addr); return NULL; -- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* [patch 09/14] SLUB: Move count_partial() 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter ` (7 preceding siblings ...) 2007-09-25 23:25 ` [patch 08/14] vunmap: return page array passed on vmap() Christoph Lameter @ 2007-09-25 23:25 ` Christoph Lameter 2007-09-25 23:25 ` [patch 10/14] SLUB: Rename NUMA defrag_ratio to remote_node_defrag_ratio Christoph Lameter ` (5 subsequent siblings) 14 siblings, 0 replies; 23+ messages in thread From: Christoph Lameter @ 2007-09-25 23:25 UTC (permalink / raw) To: akpm; +Cc: linux-mm [-- Attachment #1: 0002-slab_defrag_move_count_partial.patch --] [-- Type: text/plain, Size: 1721 bytes --] Move the counting function for objects in partial slabs so that it is placed before kmem_cache_shrink. Signed-off-by: Christoph Lameter <clameter@sgi.com> --- mm/slub.c | 26 +++++++++++++------------- 1 files changed, 13 insertions(+), 13 deletions(-) Index: linux-2.6.23-rc8-mm1/mm/slub.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/mm/slub.c 2007-09-25 15:08:14.000000000 -0700 +++ linux-2.6.23-rc8-mm1/mm/slub.c 2007-09-25 15:23:52.000000000 -0700 @@ -2626,6 +2626,19 @@ void kfree(const void *x) } EXPORT_SYMBOL(kfree); +static unsigned long count_partial(struct kmem_cache_node *n) +{ + unsigned long flags; + unsigned long x = 0; + struct page *page; + + spin_lock_irqsave(&n->list_lock, flags); + list_for_each_entry(page, &n->partial, lru) + x += page->inuse; + spin_unlock_irqrestore(&n->list_lock, flags); + return x; +} + /* * kmem_cache_shrink removes empty slabs from the partial lists and sorts * the remaining slabs by the number of items in use. The slabs with the @@ -3372,19 +3385,6 @@ static int list_locations(struct kmem_ca return n; } -static unsigned long count_partial(struct kmem_cache_node *n) -{ - unsigned long flags; - unsigned long x = 0; - struct page *page; - - spin_lock_irqsave(&n->list_lock, flags); - list_for_each_entry(page, &n->partial, lru) - x += page->inuse; - spin_unlock_irqrestore(&n->list_lock, flags); - return x; -} - enum slab_stat_type { SL_FULL, SL_PARTIAL, -- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* [patch 10/14] SLUB: Rename NUMA defrag_ratio to remote_node_defrag_ratio 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter ` (8 preceding siblings ...) 2007-09-25 23:25 ` [patch 09/14] SLUB: Move count_partial() Christoph Lameter @ 2007-09-25 23:25 ` Christoph Lameter 2007-09-25 23:25 ` [patch 11/14] SLUB: Consolidate add_partial() and add_partial_tail() to one function Christoph Lameter ` (4 subsequent siblings) 14 siblings, 0 replies; 23+ messages in thread From: Christoph Lameter @ 2007-09-25 23:25 UTC (permalink / raw) To: akpm; +Cc: linux-mm [-- Attachment #1: 0003-slab_defrag_remote_node_defrag_ratio.patch --] [-- Type: text/plain, Size: 3044 bytes --] The NUMA defrag works by allocating objects from partial slabs on remote nodes. Rename it to remote_node_defrag_ratio to be clear about this. Signed-off-by: Christoph Lameter <clameter@sgi.com> --- include/linux/slub_def.h | 5 ++++- mm/slub.c | 17 +++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) Index: linux-2.6.23-rc8-mm1/include/linux/slub_def.h =================================================================== --- linux-2.6.23-rc8-mm1.orig/include/linux/slub_def.h 2007-09-25 14:53:58.000000000 -0700 +++ linux-2.6.23-rc8-mm1/include/linux/slub_def.h 2007-09-25 14:54:43.000000000 -0700 @@ -59,7 +59,10 @@ struct kmem_cache { #endif #ifdef CONFIG_NUMA - int defrag_ratio; + /* + * Defragmentation by allocating from a remote node. + */ + int remote_node_defrag_ratio; struct kmem_cache_node *node[MAX_NUMNODES]; #endif #ifdef CONFIG_SMP Index: linux-2.6.23-rc8-mm1/mm/slub.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/mm/slub.c 2007-09-25 14:54:25.000000000 -0700 +++ linux-2.6.23-rc8-mm1/mm/slub.c 2007-09-25 14:54:43.000000000 -0700 @@ -1300,7 +1300,8 @@ static struct page *get_any_partial(stru * expensive if we do it every time we are trying to find a slab * with available objects. */ - if (!s->defrag_ratio || get_cycles() % 1024 > s->defrag_ratio) + if (!s->remote_node_defrag_ratio || + get_cycles() % 1024 > s->remote_node_defrag_ratio) return NULL; zonelist = &NODE_DATA(slab_node(current->mempolicy)) @@ -2231,7 +2232,7 @@ static int kmem_cache_open(struct kmem_c s->refcount = 1; #ifdef CONFIG_NUMA - s->defrag_ratio = 100; + s->remote_node_defrag_ratio = 100; #endif if (!init_kmem_cache_nodes(s, gfpflags & ~SLUB_DMA)) goto error; @@ -3762,21 +3763,21 @@ static ssize_t free_calls_show(struct km SLAB_ATTR_RO(free_calls); #ifdef CONFIG_NUMA -static ssize_t defrag_ratio_show(struct kmem_cache *s, char *buf) +static ssize_t remote_node_defrag_ratio_show(struct kmem_cache *s, char *buf) { - return sprintf(buf, "%d\n", s->defrag_ratio / 10); + return sprintf(buf, "%d\n", s->remote_node_defrag_ratio / 10); } -static ssize_t defrag_ratio_store(struct kmem_cache *s, +static ssize_t remote_node_defrag_ratio_store(struct kmem_cache *s, const char *buf, size_t length) { int n = simple_strtoul(buf, NULL, 10); if (n < 100) - s->defrag_ratio = n * 10; + s->remote_node_defrag_ratio = n * 10; return length; } -SLAB_ATTR(defrag_ratio); +SLAB_ATTR(remote_node_defrag_ratio); #endif static struct attribute * slab_attrs[] = { @@ -3807,7 +3808,7 @@ static struct attribute * slab_attrs[] = &cache_dma_attr.attr, #endif #ifdef CONFIG_NUMA - &defrag_ratio_attr.attr, + &remote_node_defrag_ratio_attr.attr, #endif NULL }; -- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* [patch 11/14] SLUB: Consolidate add_partial() and add_partial_tail() to one function 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter ` (9 preceding siblings ...) 2007-09-25 23:25 ` [patch 10/14] SLUB: Rename NUMA defrag_ratio to remote_node_defrag_ratio Christoph Lameter @ 2007-09-25 23:25 ` Christoph Lameter 2007-09-25 23:25 ` [patch 12/14] VM: Allow get_page_unless_zero on compound pages Christoph Lameter ` (3 subsequent siblings) 14 siblings, 0 replies; 23+ messages in thread From: Christoph Lameter @ 2007-09-25 23:25 UTC (permalink / raw) To: akpm; +Cc: linux-mm [-- Attachment #1: 0008-slab_defrag_add_partial_tail.patch --] [-- Type: text/plain, Size: 4346 bytes --] Add a parameter to add_partial instead of having separate functions. The parameter allows a more detailed control of where the slab pages is placed in the partial queues. If we put slabs back to the front then they are likely immediately used for allocations. If they are put at the end then we can maximize the time that the partial slabs spent without being subject to allocations. When deactivating slab we can put the slabs that had remote objects freed (we can see that because objects were put on the freelist that requires locks) to them at the end of the list so that the cachelines of remote processors can cool down. Slabs that had objects from the local cpu freed to them (objects exist in the lockless freelist) are put in the front of the list to be reused ASAP in order to exploit the cache hot state of the local cpu. Signed-off-by: Christoph Lameter <clameter@sgi.com> --- mm/slub.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) Index: linux-2.6.23-rc8-mm1/mm/slub.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/mm/slub.c 2007-09-25 14:54:43.000000000 -0700 +++ linux-2.6.23-rc8-mm1/mm/slub.c 2007-09-25 14:55:49.000000000 -0700 @@ -1203,19 +1203,15 @@ static __always_inline int slab_trylock( /* * Management of partially allocated slabs */ -static void add_partial_tail(struct kmem_cache_node *n, struct page *page) +static void add_partial(struct kmem_cache_node *n, + struct page *page, int tail) { spin_lock(&n->list_lock); n->nr_partial++; - list_add_tail(&page->lru, &n->partial); - spin_unlock(&n->list_lock); -} - -static void add_partial(struct kmem_cache_node *n, struct page *page) -{ - spin_lock(&n->list_lock); - n->nr_partial++; - list_add(&page->lru, &n->partial); + if (tail) + list_add_tail(&page->lru, &n->partial); + else + list_add(&page->lru, &n->partial); spin_unlock(&n->list_lock); } @@ -1344,7 +1340,7 @@ static struct page *get_partial(struct k * * On exit the slab lock will have been dropped. */ -static void unfreeze_slab(struct kmem_cache *s, struct page *page) +static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail) { struct kmem_cache_node *n = get_node(s, page_to_nid(page)); @@ -1352,7 +1348,7 @@ static void unfreeze_slab(struct kmem_ca if (page->inuse) { if (page->freelist) - add_partial(n, page); + add_partial(n, page, tail); else if (SlabDebug(page) && (s->flags & SLAB_STORE_USER)) add_full(n, page); slab_unlock(page); @@ -1367,7 +1363,7 @@ static void unfreeze_slab(struct kmem_ca * partial list stays small. kmem_cache_shrink can * reclaim empty slabs from the partial list. */ - add_partial_tail(n, page); + add_partial(n, page, 1); slab_unlock(page); } else { slab_unlock(page); @@ -1382,6 +1378,7 @@ static void unfreeze_slab(struct kmem_ca static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c) { struct page *page = c->page; + int tail = 1; /* * Merge cpu freelist into freelist. Typically we get here * because both freelists are empty. So this is unlikely @@ -1390,6 +1387,8 @@ static void deactivate_slab(struct kmem_ while (unlikely(c->freelist)) { void **object; + tail = 0; /* Hot objects. Put the slab first */ + /* Retrieve object from cpu_freelist */ object = c->freelist; c->freelist = c->freelist[c->offset]; @@ -1400,7 +1399,7 @@ static void deactivate_slab(struct kmem_ page->inuse--; } c->page = NULL; - unfreeze_slab(s, page); + unfreeze_slab(s, page, tail); } static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c) @@ -1640,7 +1639,7 @@ checks_ok: * then add it. */ if (unlikely(!prior)) - add_partial(get_node(s, page_to_nid(page)), page); + add_partial(get_node(s, page_to_nid(page)), page, 0); out_unlock: slab_unlock(page); @@ -2047,7 +2046,7 @@ static struct kmem_cache_node *early_kme #endif init_kmem_cache_node(n); atomic_long_inc(&n->nr_slabs); - add_partial(n, page); + add_partial(n, page, 0); return n; } -- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* [patch 12/14] VM: Allow get_page_unless_zero on compound pages 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter ` (10 preceding siblings ...) 2007-09-25 23:25 ` [patch 11/14] SLUB: Consolidate add_partial() and add_partial_tail() to one function Christoph Lameter @ 2007-09-25 23:25 ` Christoph Lameter 2007-09-25 23:25 ` [patch 13/14] dentries: Extract common code to remove dentry from lru Christoph Lameter ` (2 subsequent siblings) 14 siblings, 0 replies; 23+ messages in thread From: Christoph Lameter @ 2007-09-25 23:25 UTC (permalink / raw) To: akpm; +Cc: linux-mm [-- Attachment #1: 0011-slab_defrag_get_page_unless.patch --] [-- Type: text/plain, Size: 1030 bytes --] Both slab defrag and the large blocksize patches need to ability to take refcounts on compound pages. May be useful in other places as well. Signed-off-by: Christoph Lameter <clameter@sgi.com> --- include/linux/mm.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) Index: linux-2.6.23-rc8-mm1/include/linux/mm.h =================================================================== --- linux-2.6.23-rc8-mm1.orig/include/linux/mm.h 2007-09-25 14:53:58.000000000 -0700 +++ linux-2.6.23-rc8-mm1/include/linux/mm.h 2007-09-25 14:56:30.000000000 -0700 @@ -227,7 +227,7 @@ static inline int put_page_testzero(stru */ static inline int get_page_unless_zero(struct page *page) { - VM_BUG_ON(PageCompound(page)); + VM_BUG_ON(PageTail(page)); return atomic_inc_not_zero(&page->_count); } -- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* [patch 13/14] dentries: Extract common code to remove dentry from lru 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter ` (11 preceding siblings ...) 2007-09-25 23:25 ` [patch 12/14] VM: Allow get_page_unless_zero on compound pages Christoph Lameter @ 2007-09-25 23:25 ` Christoph Lameter 2007-10-22 21:29 ` Andrew Morton 2007-09-25 23:25 ` [patch 14/14] bufferhead: Revert constructor removal Christoph Lameter 2007-09-27 20:25 ` [patch 00/14] Misc cleanups / fixes Andrew Morton 14 siblings, 1 reply; 23+ messages in thread From: Christoph Lameter @ 2007-09-25 23:25 UTC (permalink / raw) To: akpm; +Cc: linux-mm [-- Attachment #1: 0023-slab_defrag_dentry_remove_lru.patch --] [-- Type: text/plain, Size: 3393 bytes --] Extract the common code to remove a dentry from the lru into a new function dentry_lru_remove(). Two call sites used list_del() instead of list_del_init(). AFAIK the performance of both is the same. dentry_lru_remove() does a list_del_init(). As a result dentry->d_lru is now always empty when a dentry is freed. Signed-off-by: Christoph Lameter <clameter@sgi.com> --- fs/dcache.c | 42 ++++++++++++++---------------------------- 1 files changed, 14 insertions(+), 28 deletions(-) Index: linux-2.6.23-rc8-mm1/fs/dcache.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/dcache.c 2007-09-25 14:53:57.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/dcache.c 2007-09-25 14:57:09.000000000 -0700 @@ -95,6 +95,14 @@ static void d_free(struct dentry *dentry call_rcu(&dentry->d_u.d_rcu, d_callback); } +static void dentry_lru_remove(struct dentry *dentry) +{ + if (!list_empty(&dentry->d_lru)) { + list_del_init(&dentry->d_lru); + dentry_stat.nr_unused--; + } +} + /* * Release the dentry's inode, using the filesystem * d_iput() operation if defined. @@ -212,13 +220,7 @@ repeat: unhash_it: __d_drop(dentry); kill_it: - /* If dentry was on d_lru list - * delete it from there - */ - if (!list_empty(&dentry->d_lru)) { - list_del(&dentry->d_lru); - dentry_stat.nr_unused--; - } + dentry_lru_remove(dentry); dentry = d_kill(dentry); if (dentry) goto repeat; @@ -286,10 +288,7 @@ int d_invalidate(struct dentry * dentry) static inline struct dentry * __dget_locked(struct dentry *dentry) { atomic_inc(&dentry->d_count); - if (!list_empty(&dentry->d_lru)) { - dentry_stat.nr_unused--; - list_del_init(&dentry->d_lru); - } + dentry_lru_remove(dentry); return dentry; } @@ -405,10 +404,7 @@ static void prune_one_dentry(struct dent if (dentry->d_op && dentry->d_op->d_delete) dentry->d_op->d_delete(dentry); - if (!list_empty(&dentry->d_lru)) { - list_del(&dentry->d_lru); - dentry_stat.nr_unused--; - } + dentry_lru_remove(dentry); __d_drop(dentry); dentry = d_kill(dentry); spin_lock(&dcache_lock); @@ -597,10 +593,7 @@ static void shrink_dcache_for_umount_sub /* detach this root from the system */ spin_lock(&dcache_lock); - if (!list_empty(&dentry->d_lru)) { - dentry_stat.nr_unused--; - list_del_init(&dentry->d_lru); - } + dentry_lru_remove(dentry); __d_drop(dentry); spin_unlock(&dcache_lock); @@ -614,11 +607,7 @@ static void shrink_dcache_for_umount_sub spin_lock(&dcache_lock); list_for_each_entry(loop, &dentry->d_subdirs, d_u.d_child) { - if (!list_empty(&loop->d_lru)) { - dentry_stat.nr_unused--; - list_del_init(&loop->d_lru); - } - + dentry_lru_remove(dentry); __d_drop(loop); cond_resched_lock(&dcache_lock); } @@ -800,10 +789,7 @@ resume: struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child); next = tmp->next; - if (!list_empty(&dentry->d_lru)) { - dentry_stat.nr_unused--; - list_del_init(&dentry->d_lru); - } + dentry_lru_remove(dentry); /* * move only zero ref count dentries to the end * of the unused list for prune_dcache -- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [patch 13/14] dentries: Extract common code to remove dentry from lru 2007-09-25 23:25 ` [patch 13/14] dentries: Extract common code to remove dentry from lru Christoph Lameter @ 2007-10-22 21:29 ` Andrew Morton 2007-10-25 2:23 ` Christoph Lameter 0 siblings, 1 reply; 23+ messages in thread From: Andrew Morton @ 2007-10-22 21:29 UTC (permalink / raw) To: Christoph Lameter; +Cc: linux-mm On Tue, 25 Sep 2007 16:25:56 -0700 Christoph Lameter <clameter@sgi.com> wrote: > Extract the common code to remove a dentry from the lru into a new function > dentry_lru_remove(). > > Two call sites used list_del() instead of list_del_init(). AFAIK the > performance of both is the same. dentry_lru_remove() does a list_del_init(). list_del() will dirty two cachelines, but list_del_init() needs to dirty a third, by writing to the to-be-removed list_head(). > As a result dentry->d_lru is now always empty when a dentry is freed. > > Signed-off-by: Christoph Lameter <clameter@sgi.com> > --- > fs/dcache.c | 42 ++++++++++++++---------------------------- > 1 files changed, 14 insertions(+), 28 deletions(-) > > Index: linux-2.6.23-rc8-mm1/fs/dcache.c > =================================================================== > --- linux-2.6.23-rc8-mm1.orig/fs/dcache.c 2007-09-25 14:53:57.000000000 -0700 > +++ linux-2.6.23-rc8-mm1/fs/dcache.c 2007-09-25 14:57:09.000000000 -0700 > @@ -95,6 +95,14 @@ static void d_free(struct dentry *dentry > call_rcu(&dentry->d_u.d_rcu, d_callback); > } > > +static void dentry_lru_remove(struct dentry *dentry) > +{ > + if (!list_empty(&dentry->d_lru)) { > + list_del_init(&dentry->d_lru); > + dentry_stat.nr_unused--; > + } > +} So can we switch this to list_del()? > /* > * Release the dentry's inode, using the filesystem > * d_iput() operation if defined. > @@ -212,13 +220,7 @@ repeat: > unhash_it: > __d_drop(dentry); > kill_it: > - /* If dentry was on d_lru list > - * delete it from there > - */ > - if (!list_empty(&dentry->d_lru)) { > - list_del(&dentry->d_lru); > - dentry_stat.nr_unused--; > - } > + dentry_lru_remove(dentry); > dentry = d_kill(dentry); > if (dentry) > goto repeat; > @@ -286,10 +288,7 @@ int d_invalidate(struct dentry * dentry) > static inline struct dentry * __dget_locked(struct dentry *dentry) > { > atomic_inc(&dentry->d_count); > - if (!list_empty(&dentry->d_lru)) { > - dentry_stat.nr_unused--; > - list_del_init(&dentry->d_lru); > - } No, we can't. > + dentry_lru_remove(dentry); > return dentry; > } > > @@ -405,10 +404,7 @@ static void prune_one_dentry(struct dent > > if (dentry->d_op && dentry->d_op->d_delete) > dentry->d_op->d_delete(dentry); > - if (!list_empty(&dentry->d_lru)) { > - list_del(&dentry->d_lru); > - dentry_stat.nr_unused--; > - } > + dentry_lru_remove(dentry); > __d_drop(dentry); > dentry = d_kill(dentry); > spin_lock(&dcache_lock); > @@ -597,10 +593,7 @@ static void shrink_dcache_for_umount_sub > > /* detach this root from the system */ > spin_lock(&dcache_lock); > - if (!list_empty(&dentry->d_lru)) { > - dentry_stat.nr_unused--; > - list_del_init(&dentry->d_lru); > - } > + dentry_lru_remove(dentry); > __d_drop(dentry); > spin_unlock(&dcache_lock); > > @@ -614,11 +607,7 @@ static void shrink_dcache_for_umount_sub > spin_lock(&dcache_lock); > list_for_each_entry(loop, &dentry->d_subdirs, > d_u.d_child) { > - if (!list_empty(&loop->d_lru)) { > - dentry_stat.nr_unused--; > - list_del_init(&loop->d_lru); > - } > - > + dentry_lru_remove(dentry); > __d_drop(loop); > cond_resched_lock(&dcache_lock); > } > @@ -800,10 +789,7 @@ resume: > struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child); > next = tmp->next; > > - if (!list_empty(&dentry->d_lru)) { > - dentry_stat.nr_unused--; > - list_del_init(&dentry->d_lru); > - } > + dentry_lru_remove(dentry); Doesn't seem like a terribly good change to me - it's one of those cant-measure-a-difference changes which add up to a slower kernel after we've merged three years worth of them. Perhaps not all of those list_del_init() callers actually need to be using the _init version? -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [patch 13/14] dentries: Extract common code to remove dentry from lru 2007-10-22 21:29 ` Andrew Morton @ 2007-10-25 2:23 ` Christoph Lameter 2007-10-25 2:34 ` Andrew Morton 0 siblings, 1 reply; 23+ messages in thread From: Christoph Lameter @ 2007-10-25 2:23 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-mm On Mon, 22 Oct 2007, Andrew Morton wrote: > Doesn't seem like a terribly good change to me - it's one of those > cant-measure-a-difference changes which add up to a slower kernel after > we've merged three years worth of them. > > Perhaps not all of those list_del_init() callers actually need to be using > the _init version? Sometimes we check the list head using list_empty() so we cannot avoid list_del_init. Always using list_del_init results in a consistent state of affairs before the object is freed (which the slab defrag patchset depends on) -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [patch 13/14] dentries: Extract common code to remove dentry from lru 2007-10-25 2:23 ` Christoph Lameter @ 2007-10-25 2:34 ` Andrew Morton 2007-10-25 2:50 ` Christoph Lameter 0 siblings, 1 reply; 23+ messages in thread From: Andrew Morton @ 2007-10-25 2:34 UTC (permalink / raw) To: Christoph Lameter; +Cc: linux-mm On Wed, 24 Oct 2007 19:23:36 -0700 (PDT) Christoph Lameter <clameter@sgi.com> wrote: > On Mon, 22 Oct 2007, Andrew Morton wrote: > > > Doesn't seem like a terribly good change to me - it's one of those > > cant-measure-a-difference changes which add up to a slower kernel after > > we've merged three years worth of them. > > > > Perhaps not all of those list_del_init() callers actually need to be using > > the _init version? > > Sometimes we check the list head using list_empty() so we cannot avoid > list_del_init. Always using list_del_init results in a consistent state of > affairs before the object is freed (which the slab defrag patchset depends > on) OK, but it's slower. So I think it should be changlogged as such, with an explanation that there will (hopefully) be a net benefit because it enables slab defrag, and it should be moved into the slab-defrag patchset. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [patch 13/14] dentries: Extract common code to remove dentry from lru 2007-10-25 2:34 ` Andrew Morton @ 2007-10-25 2:50 ` Christoph Lameter 2007-10-25 3:03 ` Andrew Morton 0 siblings, 1 reply; 23+ messages in thread From: Christoph Lameter @ 2007-10-25 2:50 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-mm On Wed, 24 Oct 2007, Andrew Morton wrote: > > Sometimes we check the list head using list_empty() so we cannot avoid > > list_del_init. Always using list_del_init results in a consistent state of > > affairs before the object is freed (which the slab defrag patchset depends > > on) > > OK, but it's slower. > > So I think it should be changlogged as such, with an explanation that there > will (hopefully) be a net benefit because it enables slab defrag, and it > should be moved into the slab-defrag patchset. really? list_del_init does: static inline void list_del_init(struct list_head *entry) { __list_del(entry->prev, entry->next); INIT_LIST_HEAD(entry); } So it touches the cachelines of the entry and prev/next to fix up the links. list_del does: #ifndef CONFIG_DEBUG_LIST static inline void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); entry->next = LIST_POISON1; entry->prev = LIST_POISON2; } #else extern void list_del(struct list_head *entry); #endif In the !DEBUG case it touches the same cachelines. The only change is that we poison entry. So its not slower. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [patch 13/14] dentries: Extract common code to remove dentry from lru 2007-10-25 2:50 ` Christoph Lameter @ 2007-10-25 3:03 ` Andrew Morton 0 siblings, 0 replies; 23+ messages in thread From: Andrew Morton @ 2007-10-25 3:03 UTC (permalink / raw) To: Christoph Lameter; +Cc: linux-mm, David Howells, Oleg Nesterov x On Wed, 24 Oct 2007 19:50:19 -0700 (PDT) Christoph Lameter <clameter@sgi.com> wrote: > On Wed, 24 Oct 2007, Andrew Morton wrote: > > > > Sometimes we check the list head using list_empty() so we cannot avoid > > > list_del_init. Always using list_del_init results in a consistent state of > > > affairs before the object is freed (which the slab defrag patchset depends > > > on) > > > > OK, but it's slower. > > > > So I think it should be changlogged as such, with an explanation that there > > will (hopefully) be a net benefit because it enables slab defrag, and it > > should be moved into the slab-defrag patchset. > > really? > > list_del_init does: > > static inline void list_del_init(struct list_head *entry) > { > __list_del(entry->prev, entry->next); > INIT_LIST_HEAD(entry); > } > > So it touches the cachelines of the entry and prev/next to fix up the > links. > > list_del does: > > #ifndef CONFIG_DEBUG_LIST > static inline void list_del(struct list_head *entry) > { > __list_del(entry->prev, entry->next); > entry->next = LIST_POISON1; > entry->prev = LIST_POISON2; > } > #else > extern void list_del(struct list_head *entry); > #endif > > In the !DEBUG case it touches the same cachelines. The only change is that > we poison entry. bugger, I'd forgotten that we do the poisoning even if !CONFIG_DEBUG_LIST. We really shouldn't do that, especially now that we have the list debugging config option. Fixing this might break net/rxrpc/af_rxrpc.c and detach_timer(), but they deserve to be broken. > So its not slower. It should be. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* [patch 14/14] bufferhead: Revert constructor removal 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter ` (12 preceding siblings ...) 2007-09-25 23:25 ` [patch 13/14] dentries: Extract common code to remove dentry from lru Christoph Lameter @ 2007-09-25 23:25 ` Christoph Lameter 2007-10-22 21:31 ` Andrew Morton 2007-09-27 20:25 ` [patch 00/14] Misc cleanups / fixes Andrew Morton 14 siblings, 1 reply; 23+ messages in thread From: Christoph Lameter @ 2007-09-25 23:25 UTC (permalink / raw) To: akpm; +Cc: linux-mm [-- Attachment #1: 0015-slab_defrag_buffer_head_revert.patch --] [-- Type: text/plain, Size: 1845 bytes --] The constructor for buffer_head slabs was removed recently. We need the constructor back in slab defrag in order to insure that slab objects always have a definite state even before we allocated them. Signed-off-by: Christoph Lameter <clameter@sgi.com> --- fs/buffer.c | 19 +++++++++++++++---- 1 files changed, 15 insertions(+), 4 deletions(-) Index: linux-2.6.23-rc8-mm1/fs/buffer.c =================================================================== --- linux-2.6.23-rc8-mm1.orig/fs/buffer.c 2007-09-25 15:14:40.000000000 -0700 +++ linux-2.6.23-rc8-mm1/fs/buffer.c 2007-09-25 15:36:50.000000000 -0700 @@ -3093,7 +3093,7 @@ static void recalc_bh_state(void) struct buffer_head *alloc_buffer_head(gfp_t gfp_flags) { - struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, + struct buffer_head *ret = kmem_cache_alloc(bh_cachep, set_migrateflags(gfp_flags, __GFP_RECLAIMABLE)); if (ret) { INIT_LIST_HEAD(&ret->b_assoc_buffers); @@ -3137,12 +3137,24 @@ static int buffer_cpu_notify(struct noti return NOTIFY_OK; } +static void +init_buffer_head(struct kmem_cache *cachep, void *data) +{ + struct buffer_head * bh = (struct buffer_head *)data; + + memset(bh, 0, sizeof(*bh)); + INIT_LIST_HEAD(&bh->b_assoc_buffers); +} + void __init buffer_init(void) { int nrpages; - bh_cachep = KMEM_CACHE(buffer_head, - SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|SLAB_MEM_SPREAD); + bh_cachep = kmem_cache_create("buffer_head", + sizeof(struct buffer_head), 0, + (SLAB_RECLAIM_ACCOUNT|SLAB_PANIC| + SLAB_MEM_SPREAD), + init_buffer_head); /* * Limit the bh occupancy to 10% of ZONE_NORMAL -- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [patch 14/14] bufferhead: Revert constructor removal 2007-09-25 23:25 ` [patch 14/14] bufferhead: Revert constructor removal Christoph Lameter @ 2007-10-22 21:31 ` Andrew Morton 2007-10-25 2:25 ` Christoph Lameter 0 siblings, 1 reply; 23+ messages in thread From: Andrew Morton @ 2007-10-22 21:31 UTC (permalink / raw) To: Christoph Lameter; +Cc: linux-mm On Tue, 25 Sep 2007 16:25:57 -0700 Christoph Lameter <clameter@sgi.com> wrote: > The constructor for buffer_head slabs was removed recently. We need > the constructor back in slab defrag in order to insure that slab objects > always have a definite state even before we allocated them. > I don't understand. Slab defrag isn't merged. > > --- > fs/buffer.c | 19 +++++++++++++++---- > 1 files changed, 15 insertions(+), 4 deletions(-) > > Index: linux-2.6.23-rc8-mm1/fs/buffer.c > =================================================================== > --- linux-2.6.23-rc8-mm1.orig/fs/buffer.c 2007-09-25 15:14:40.000000000 -0700 > +++ linux-2.6.23-rc8-mm1/fs/buffer.c 2007-09-25 15:36:50.000000000 -0700 > @@ -3093,7 +3093,7 @@ static void recalc_bh_state(void) > > struct buffer_head *alloc_buffer_head(gfp_t gfp_flags) > { > - struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, > + struct buffer_head *ret = kmem_cache_alloc(bh_cachep, > set_migrateflags(gfp_flags, __GFP_RECLAIMABLE)); > if (ret) { > INIT_LIST_HEAD(&ret->b_assoc_buffers); > @@ -3137,12 +3137,24 @@ static int buffer_cpu_notify(struct noti > return NOTIFY_OK; > } > > +static void > +init_buffer_head(struct kmem_cache *cachep, void *data) > +{ > + struct buffer_head * bh = (struct buffer_head *)data; > + > + memset(bh, 0, sizeof(*bh)); > + INIT_LIST_HEAD(&bh->b_assoc_buffers); > +} > + > void __init buffer_init(void) > { > int nrpages; > > - bh_cachep = KMEM_CACHE(buffer_head, > - SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|SLAB_MEM_SPREAD); > + bh_cachep = kmem_cache_create("buffer_head", > + sizeof(struct buffer_head), 0, > + (SLAB_RECLAIM_ACCOUNT|SLAB_PANIC| > + SLAB_MEM_SPREAD), > + init_buffer_head); > So I see no need for this patch? Shouldn't it be part of a slab-defrag patch series? -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [patch 14/14] bufferhead: Revert constructor removal 2007-10-22 21:31 ` Andrew Morton @ 2007-10-25 2:25 ` Christoph Lameter 0 siblings, 0 replies; 23+ messages in thread From: Christoph Lameter @ 2007-10-25 2:25 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-mm On Mon, 22 Oct 2007, Andrew Morton wrote: > So I see no need for this patch? Shouldn't it be part of a slab-defrag > patch series? It could be part of it. However, I think we mistakenly merged the removal of the constuctor into a cleanup patch. You had a test that showed that the removal of the constructor led to a small regression. The prior state makes things easier for slab defrag. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [patch 00/14] Misc cleanups / fixes 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter ` (13 preceding siblings ...) 2007-09-25 23:25 ` [patch 14/14] bufferhead: Revert constructor removal Christoph Lameter @ 2007-09-27 20:25 ` Andrew Morton 14 siblings, 0 replies; 23+ messages in thread From: Andrew Morton @ 2007-09-27 20:25 UTC (permalink / raw) To: Christoph Lameter; +Cc: linux-mm On Tue, 25 Sep 2007 16:25:43 -0700 Christoph Lameter <clameter@sgi.com> wrote: > This is a collection of fixes and cleanups from the slab defrag, > virtual compound and the large block patchset that are useful > independent of these patchsets and that were rediffed against > 2.6.23-rc8-mm1. Christoph, I think I'll duck these for now - I'm a bit worried about the even-worse-than-usual stability levels in the 2.6.24 lineup, so I'd prefer not to churn things in a way which will distract from fixing all that up. I'll keep the patches, see if I can get them to apply and work around the -rc1 timeframe. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2007-10-25 3:03 UTC | newest] Thread overview: 23+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-09-25 23:25 [patch 00/14] Misc cleanups / fixes Christoph Lameter 2007-09-25 23:25 ` [patch 01/14] Pagecache zeroing: zero_user_segment, zero_user_segments and zero_user Christoph Lameter 2007-09-25 23:25 ` [patch 02/14] Reiser4 portion of zero_user cleanup patch Christoph Lameter 2007-09-25 23:25 ` [patch 03/14] Move vmalloc_to_page() to mm/vmalloc Christoph Lameter 2007-09-25 23:25 ` [patch 04/14] vmalloc: add const to void ..tmp_kallsyms1.o.cmd ..tmp_kallsyms2.o.cmd ..tmp_vmlinux1.cmd ..tmp_vmlinux2.cmd .cf .cf1 .cf2 .cf3 .cfnet .config .config.old .gitignore .mailmap .missing-syscalls.d .pc .tmp_System.map .tmp_kallsyms1.S .tmp_kallsyms1.o .tmp_kallsyms2.S .tmp_kallsyms2.o .tmp_versions .tmp_vmlinux1 .tmp_vmlinux2 .version .vmlinux.cmd .vmlinux.o.cmd COPYING CREDITS Documentation Kbuild MAINTAINERS Makefile Module.symvers README REPORTING-BUGS System.map arch b block crypto drivers fs include init ipc kernel lib linux-2.6.23-rc8-mm1.tar.gz mips mm net patches scripts security sound tar-install test test_out usr vmlinux vmlinux.gz vmlinux.o vmlinux.sym xx parameters Christoph Lameter 2007-09-25 23:25 ` [patch 05/14] i386: Resolve dependency of asm-i386/pgtable.h on highmem.h Christoph Lameter 2007-09-25 23:25 ` [patch 06/14] is_vmalloc_addr(): Check if an address is within the vmalloc boundaries Christoph Lameter 2007-09-25 23:25 ` [patch 07/14] vmalloc: Clean up page array indexing Christoph Lameter 2007-09-25 23:25 ` [patch 08/14] vunmap: return page array passed on vmap() Christoph Lameter 2007-09-25 23:25 ` [patch 09/14] SLUB: Move count_partial() Christoph Lameter 2007-09-25 23:25 ` [patch 10/14] SLUB: Rename NUMA defrag_ratio to remote_node_defrag_ratio Christoph Lameter 2007-09-25 23:25 ` [patch 11/14] SLUB: Consolidate add_partial() and add_partial_tail() to one function Christoph Lameter 2007-09-25 23:25 ` [patch 12/14] VM: Allow get_page_unless_zero on compound pages Christoph Lameter 2007-09-25 23:25 ` [patch 13/14] dentries: Extract common code to remove dentry from lru Christoph Lameter 2007-10-22 21:29 ` Andrew Morton 2007-10-25 2:23 ` Christoph Lameter 2007-10-25 2:34 ` Andrew Morton 2007-10-25 2:50 ` Christoph Lameter 2007-10-25 3:03 ` Andrew Morton 2007-09-25 23:25 ` [patch 14/14] bufferhead: Revert constructor removal Christoph Lameter 2007-10-22 21:31 ` Andrew Morton 2007-10-25 2:25 ` Christoph Lameter 2007-09-27 20:25 ` [patch 00/14] Misc cleanups / fixes Andrew Morton
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).