aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.mailmap4
-rw-r--r--fs/hfsplus/catalog.c89
-rw-r--r--fs/hfsplus/dir.c11
-rw-r--r--fs/hfsplus/hfsplus_fs.h4
-rw-r--r--fs/hfsplus/super.c4
-rw-r--r--fs/ocfs2/alloc.c28
-rw-r--r--fs/ocfs2/alloc.h2
-rw-r--r--fs/ocfs2/aops.c16
-rw-r--r--fs/ocfs2/dir.c2
-rw-r--r--fs/ocfs2/dlm/dlmmaster.c12
-rw-r--r--fs/ocfs2/file.c2
-rw-r--r--fs/proc/meminfo.c15
-rw-r--r--include/linux/cma.h1
-rw-r--r--lib/show_mem.c6
-rw-r--r--mm/cma.c1
-rw-r--r--mm/memory.c6
-rw-r--r--mm/mempolicy.c10
-rw-r--r--mm/page_alloc.c6
-rw-r--r--mm/zsmalloc.c374
-rw-r--r--tools/testing/selftests/Makefile17
20 files changed, 352 insertions, 258 deletions
diff --git a/.mailmap b/.mailmap
index 1ad68731fb47..ada8ad696b2e 100644
--- a/.mailmap
+++ b/.mailmap
@@ -17,7 +17,7 @@ Aleksey Gorelov <aleksey_gorelov@phoenix.com>
17Al Viro <viro@ftp.linux.org.uk> 17Al Viro <viro@ftp.linux.org.uk>
18Al Viro <viro@zenIV.linux.org.uk> 18Al Viro <viro@zenIV.linux.org.uk>
19Andreas Herrmann <aherrman@de.ibm.com> 19Andreas Herrmann <aherrman@de.ibm.com>
20Andrew Morton <akpm@osdl.org> 20Andrew Morton <akpm@linux-foundation.org>
21Andrew Vasquez <andrew.vasquez@qlogic.com> 21Andrew Vasquez <andrew.vasquez@qlogic.com>
22Andy Adamson <andros@citi.umich.edu> 22Andy Adamson <andros@citi.umich.edu>
23Archit Taneja <archit@ti.com> 23Archit Taneja <archit@ti.com>
@@ -102,6 +102,8 @@ Rudolf Marek <R.Marek@sh.cvut.cz>
102Rui Saraiva <rmps@joel.ist.utl.pt> 102Rui Saraiva <rmps@joel.ist.utl.pt>
103Sachin P Sant <ssant@in.ibm.com> 103Sachin P Sant <ssant@in.ibm.com>
104Sam Ravnborg <sam@mars.ravnborg.org> 104Sam Ravnborg <sam@mars.ravnborg.org>
105Santosh Shilimkar <ssantosh@kernel.org>
106Santosh Shilimkar <santosh.shilimkar@oracle.org>
105Sascha Hauer <s.hauer@pengutronix.de> 107Sascha Hauer <s.hauer@pengutronix.de>
106S.Çağlar Onur <caglar@pardus.org.tr> 108S.Çağlar Onur <caglar@pardus.org.tr>
107Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com> 109Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com>
diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c
index 32602c667b4a..7892e6fddb66 100644
--- a/fs/hfsplus/catalog.c
+++ b/fs/hfsplus/catalog.c
@@ -38,21 +38,30 @@ int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *k1,
38 return hfsplus_strcmp(&k1->cat.name, &k2->cat.name); 38 return hfsplus_strcmp(&k1->cat.name, &k2->cat.name);
39} 39}
40 40
41void hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *key, 41/* Generates key for catalog file/folders record. */
42 u32 parent, struct qstr *str) 42int hfsplus_cat_build_key(struct super_block *sb,
43 hfsplus_btree_key *key, u32 parent, struct qstr *str)
43{ 44{
44 int len; 45 int len, err;
45 46
46 key->cat.parent = cpu_to_be32(parent); 47 key->cat.parent = cpu_to_be32(parent);
47 if (str) { 48 err = hfsplus_asc2uni(sb, &key->cat.name, HFSPLUS_MAX_STRLEN,
48 hfsplus_asc2uni(sb, &key->cat.name, HFSPLUS_MAX_STRLEN, 49 str->name, str->len);
49 str->name, str->len); 50 if (unlikely(err < 0))
50 len = be16_to_cpu(key->cat.name.length); 51 return err;
51 } else { 52
52 key->cat.name.length = 0; 53 len = be16_to_cpu(key->cat.name.length);
53 len = 0;
54 }
55 key->key_len = cpu_to_be16(6 + 2 * len); 54 key->key_len = cpu_to_be16(6 + 2 * len);
55 return 0;
56}
57
58/* Generates key for catalog thread record. */
59void hfsplus_cat_build_key_with_cnid(struct super_block *sb,
60 hfsplus_btree_key *key, u32 parent)
61{
62 key->cat.parent = cpu_to_be32(parent);
63 key->cat.name.length = 0;
64 key->key_len = cpu_to_be16(6);
56} 65}
57 66
58static void hfsplus_cat_build_key_uni(hfsplus_btree_key *key, u32 parent, 67static void hfsplus_cat_build_key_uni(hfsplus_btree_key *key, u32 parent,
@@ -167,11 +176,16 @@ static int hfsplus_fill_cat_thread(struct super_block *sb,
167 hfsplus_cat_entry *entry, int type, 176 hfsplus_cat_entry *entry, int type,
168 u32 parentid, struct qstr *str) 177 u32 parentid, struct qstr *str)
169{ 178{
179 int err;
180
170 entry->type = cpu_to_be16(type); 181 entry->type = cpu_to_be16(type);
171 entry->thread.reserved = 0; 182 entry->thread.reserved = 0;
172 entry->thread.parentID = cpu_to_be32(parentid); 183 entry->thread.parentID = cpu_to_be32(parentid);
173 hfsplus_asc2uni(sb, &entry->thread.nodeName, HFSPLUS_MAX_STRLEN, 184 err = hfsplus_asc2uni(sb, &entry->thread.nodeName, HFSPLUS_MAX_STRLEN,
174 str->name, str->len); 185 str->name, str->len);
186 if (unlikely(err < 0))
187 return err;
188
175 return 10 + be16_to_cpu(entry->thread.nodeName.length) * 2; 189 return 10 + be16_to_cpu(entry->thread.nodeName.length) * 2;
176} 190}
177 191
@@ -183,7 +197,7 @@ int hfsplus_find_cat(struct super_block *sb, u32 cnid,
183 int err; 197 int err;
184 u16 type; 198 u16 type;
185 199
186 hfsplus_cat_build_key(sb, fd->search_key, cnid, NULL); 200 hfsplus_cat_build_key_with_cnid(sb, fd->search_key, cnid);
187 err = hfs_brec_read(fd, &tmp, sizeof(hfsplus_cat_entry)); 201 err = hfs_brec_read(fd, &tmp, sizeof(hfsplus_cat_entry));
188 if (err) 202 if (err)
189 return err; 203 return err;
@@ -250,11 +264,16 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir,
250 if (err) 264 if (err)
251 return err; 265 return err;
252 266
253 hfsplus_cat_build_key(sb, fd.search_key, cnid, NULL); 267 hfsplus_cat_build_key_with_cnid(sb, fd.search_key, cnid);
254 entry_size = hfsplus_fill_cat_thread(sb, &entry, 268 entry_size = hfsplus_fill_cat_thread(sb, &entry,
255 S_ISDIR(inode->i_mode) ? 269 S_ISDIR(inode->i_mode) ?
256 HFSPLUS_FOLDER_THREAD : HFSPLUS_FILE_THREAD, 270 HFSPLUS_FOLDER_THREAD : HFSPLUS_FILE_THREAD,
257 dir->i_ino, str); 271 dir->i_ino, str);
272 if (unlikely(entry_size < 0)) {
273 err = entry_size;
274 goto err2;
275 }
276
258 err = hfs_brec_find(&fd, hfs_find_rec_by_key); 277 err = hfs_brec_find(&fd, hfs_find_rec_by_key);
259 if (err != -ENOENT) { 278 if (err != -ENOENT) {
260 if (!err) 279 if (!err)
@@ -265,7 +284,10 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir,
265 if (err) 284 if (err)
266 goto err2; 285 goto err2;
267 286
268 hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str); 287 err = hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str);
288 if (unlikely(err))
289 goto err1;
290
269 entry_size = hfsplus_cat_build_record(&entry, cnid, inode); 291 entry_size = hfsplus_cat_build_record(&entry, cnid, inode);
270 err = hfs_brec_find(&fd, hfs_find_rec_by_key); 292 err = hfs_brec_find(&fd, hfs_find_rec_by_key);
271 if (err != -ENOENT) { 293 if (err != -ENOENT) {
@@ -288,7 +310,7 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir,
288 return 0; 310 return 0;
289 311
290err1: 312err1:
291 hfsplus_cat_build_key(sb, fd.search_key, cnid, NULL); 313 hfsplus_cat_build_key_with_cnid(sb, fd.search_key, cnid);
292 if (!hfs_brec_find(&fd, hfs_find_rec_by_key)) 314 if (!hfs_brec_find(&fd, hfs_find_rec_by_key))
293 hfs_brec_remove(&fd); 315 hfs_brec_remove(&fd);
294err2: 316err2:
@@ -313,7 +335,7 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str)
313 if (!str) { 335 if (!str) {
314 int len; 336 int len;
315 337
316 hfsplus_cat_build_key(sb, fd.search_key, cnid, NULL); 338 hfsplus_cat_build_key_with_cnid(sb, fd.search_key, cnid);
317 err = hfs_brec_find(&fd, hfs_find_rec_by_key); 339 err = hfs_brec_find(&fd, hfs_find_rec_by_key);
318 if (err) 340 if (err)
319 goto out; 341 goto out;
@@ -329,7 +351,9 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str)
329 off + 2, len); 351 off + 2, len);
330 fd.search_key->key_len = cpu_to_be16(6 + len); 352 fd.search_key->key_len = cpu_to_be16(6 + len);
331 } else 353 } else
332 hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str); 354 err = hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str);
355 if (unlikely(err))
356 goto out;
333 357
334 err = hfs_brec_find(&fd, hfs_find_rec_by_key); 358 err = hfs_brec_find(&fd, hfs_find_rec_by_key);
335 if (err) 359 if (err)
@@ -360,7 +384,7 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str)
360 if (err) 384 if (err)
361 goto out; 385 goto out;
362 386
363 hfsplus_cat_build_key(sb, fd.search_key, cnid, NULL); 387 hfsplus_cat_build_key_with_cnid(sb, fd.search_key, cnid);
364 err = hfs_brec_find(&fd, hfs_find_rec_by_key); 388 err = hfs_brec_find(&fd, hfs_find_rec_by_key);
365 if (err) 389 if (err)
366 goto out; 390 goto out;
@@ -405,7 +429,11 @@ int hfsplus_rename_cat(u32 cnid,
405 dst_fd = src_fd; 429 dst_fd = src_fd;
406 430
407 /* find the old dir entry and read the data */ 431 /* find the old dir entry and read the data */
408 hfsplus_cat_build_key(sb, src_fd.search_key, src_dir->i_ino, src_name); 432 err = hfsplus_cat_build_key(sb, src_fd.search_key,
433 src_dir->i_ino, src_name);
434 if (unlikely(err))
435 goto out;
436
409 err = hfs_brec_find(&src_fd, hfs_find_rec_by_key); 437 err = hfs_brec_find(&src_fd, hfs_find_rec_by_key);
410 if (err) 438 if (err)
411 goto out; 439 goto out;
@@ -419,7 +447,11 @@ int hfsplus_rename_cat(u32 cnid,
419 type = be16_to_cpu(entry.type); 447 type = be16_to_cpu(entry.type);
420 448
421 /* create new dir entry with the data from the old entry */ 449 /* create new dir entry with the data from the old entry */
422 hfsplus_cat_build_key(sb, dst_fd.search_key, dst_dir->i_ino, dst_name); 450 err = hfsplus_cat_build_key(sb, dst_fd.search_key,
451 dst_dir->i_ino, dst_name);
452 if (unlikely(err))
453 goto out;
454
423 err = hfs_brec_find(&dst_fd, hfs_find_rec_by_key); 455 err = hfs_brec_find(&dst_fd, hfs_find_rec_by_key);
424 if (err != -ENOENT) { 456 if (err != -ENOENT) {
425 if (!err) 457 if (!err)
@@ -436,7 +468,11 @@ int hfsplus_rename_cat(u32 cnid,
436 dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME_SEC; 468 dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME_SEC;
437 469
438 /* finally remove the old entry */ 470 /* finally remove the old entry */
439 hfsplus_cat_build_key(sb, src_fd.search_key, src_dir->i_ino, src_name); 471 err = hfsplus_cat_build_key(sb, src_fd.search_key,
472 src_dir->i_ino, src_name);
473 if (unlikely(err))
474 goto out;
475
440 err = hfs_brec_find(&src_fd, hfs_find_rec_by_key); 476 err = hfs_brec_find(&src_fd, hfs_find_rec_by_key);
441 if (err) 477 if (err)
442 goto out; 478 goto out;
@@ -449,7 +485,7 @@ int hfsplus_rename_cat(u32 cnid,
449 src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME_SEC; 485 src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME_SEC;
450 486
451 /* remove old thread entry */ 487 /* remove old thread entry */
452 hfsplus_cat_build_key(sb, src_fd.search_key, cnid, NULL); 488 hfsplus_cat_build_key_with_cnid(sb, src_fd.search_key, cnid);
453 err = hfs_brec_find(&src_fd, hfs_find_rec_by_key); 489 err = hfs_brec_find(&src_fd, hfs_find_rec_by_key);
454 if (err) 490 if (err)
455 goto out; 491 goto out;
@@ -459,9 +495,14 @@ int hfsplus_rename_cat(u32 cnid,
459 goto out; 495 goto out;
460 496
461 /* create new thread entry */ 497 /* create new thread entry */
462 hfsplus_cat_build_key(sb, dst_fd.search_key, cnid, NULL); 498 hfsplus_cat_build_key_with_cnid(sb, dst_fd.search_key, cnid);
463 entry_size = hfsplus_fill_cat_thread(sb, &entry, type, 499 entry_size = hfsplus_fill_cat_thread(sb, &entry, type,
464 dst_dir->i_ino, dst_name); 500 dst_dir->i_ino, dst_name);
501 if (unlikely(entry_size < 0)) {
502 err = entry_size;
503 goto out;
504 }
505
465 err = hfs_brec_find(&dst_fd, hfs_find_rec_by_key); 506 err = hfs_brec_find(&dst_fd, hfs_find_rec_by_key);
466 if (err != -ENOENT) { 507 if (err != -ENOENT) {
467 if (!err) 508 if (!err)
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 610a3260bef1..435bea231cc6 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -44,7 +44,10 @@ static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry,
44 err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); 44 err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd);
45 if (err) 45 if (err)
46 return ERR_PTR(err); 46 return ERR_PTR(err);
47 hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, &dentry->d_name); 47 err = hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino,
48 &dentry->d_name);
49 if (unlikely(err < 0))
50 goto fail;
48again: 51again:
49 err = hfs_brec_read(&fd, &entry, sizeof(entry)); 52 err = hfs_brec_read(&fd, &entry, sizeof(entry));
50 if (err) { 53 if (err) {
@@ -97,9 +100,11 @@ again:
97 be32_to_cpu(entry.file.permissions.dev); 100 be32_to_cpu(entry.file.permissions.dev);
98 str.len = sprintf(name, "iNode%d", linkid); 101 str.len = sprintf(name, "iNode%d", linkid);
99 str.name = name; 102 str.name = name;
100 hfsplus_cat_build_key(sb, fd.search_key, 103 err = hfsplus_cat_build_key(sb, fd.search_key,
101 HFSPLUS_SB(sb)->hidden_dir->i_ino, 104 HFSPLUS_SB(sb)->hidden_dir->i_ino,
102 &str); 105 &str);
106 if (unlikely(err < 0))
107 goto fail;
103 goto again; 108 goto again;
104 } 109 }
105 } else if (!dentry->d_fsdata) 110 } else if (!dentry->d_fsdata)
@@ -145,7 +150,7 @@ static int hfsplus_readdir(struct file *file, struct dir_context *ctx)
145 err = -ENOMEM; 150 err = -ENOMEM;
146 goto out; 151 goto out;
147 } 152 }
148 hfsplus_cat_build_key(sb, fd.search_key, inode->i_ino, NULL); 153 hfsplus_cat_build_key_with_cnid(sb, fd.search_key, inode->i_ino);
149 err = hfs_brec_find(&fd, hfs_find_rec_by_key); 154 err = hfs_brec_find(&fd, hfs_find_rec_by_key);
150 if (err) 155 if (err)
151 goto out; 156 goto out;
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index eb5e059f481a..b0441d65fa54 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -443,8 +443,10 @@ int hfsplus_cat_case_cmp_key(const hfsplus_btree_key *k1,
443 const hfsplus_btree_key *k2); 443 const hfsplus_btree_key *k2);
444int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *k1, 444int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *k1,
445 const hfsplus_btree_key *k2); 445 const hfsplus_btree_key *k2);
446void hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *key, 446int hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *key,
447 u32 parent, struct qstr *str); 447 u32 parent, struct qstr *str);
448void hfsplus_cat_build_key_with_cnid(struct super_block *sb,
449 hfsplus_btree_key *key, u32 parent);
448void hfsplus_cat_set_perms(struct inode *inode, struct hfsplus_perm *perms); 450void hfsplus_cat_set_perms(struct inode *inode, struct hfsplus_perm *perms);
449int hfsplus_find_cat(struct super_block *sb, u32 cnid, 451int hfsplus_find_cat(struct super_block *sb, u32 cnid,
450 struct hfs_find_data *fd); 452 struct hfs_find_data *fd);
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 4cf2024b87da..593af2fdcc2d 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -515,7 +515,9 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
515 err = hfs_find_init(sbi->cat_tree, &fd); 515 err = hfs_find_init(sbi->cat_tree, &fd);
516 if (err) 516 if (err)
517 goto out_put_root; 517 goto out_put_root;
518 hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str); 518 err = hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str);
519 if (unlikely(err < 0))
520 goto out_put_root;
519 if (!hfs_brec_read(&fd, &entry, sizeof(entry))) { 521 if (!hfs_brec_read(&fd, &entry, sizeof(entry))) {
520 hfs_find_exit(&fd); 522 hfs_find_exit(&fd);
521 if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) 523 if (entry.type != cpu_to_be16(HFSPLUS_FOLDER))
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index a93bf9892256..fcae9ef1a328 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -5662,7 +5662,7 @@ int ocfs2_remove_btree_range(struct inode *inode,
5662 struct ocfs2_extent_tree *et, 5662 struct ocfs2_extent_tree *et,
5663 u32 cpos, u32 phys_cpos, u32 len, int flags, 5663 u32 cpos, u32 phys_cpos, u32 len, int flags,
5664 struct ocfs2_cached_dealloc_ctxt *dealloc, 5664 struct ocfs2_cached_dealloc_ctxt *dealloc,
5665 u64 refcount_loc) 5665 u64 refcount_loc, bool refcount_tree_locked)
5666{ 5666{
5667 int ret, credits = 0, extra_blocks = 0; 5667 int ret, credits = 0, extra_blocks = 0;
5668 u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos); 5668 u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos);
@@ -5676,11 +5676,13 @@ int ocfs2_remove_btree_range(struct inode *inode,
5676 BUG_ON(!(OCFS2_I(inode)->ip_dyn_features & 5676 BUG_ON(!(OCFS2_I(inode)->ip_dyn_features &
5677 OCFS2_HAS_REFCOUNT_FL)); 5677 OCFS2_HAS_REFCOUNT_FL));
5678 5678
5679 ret = ocfs2_lock_refcount_tree(osb, refcount_loc, 1, 5679 if (!refcount_tree_locked) {
5680 &ref_tree, NULL); 5680 ret = ocfs2_lock_refcount_tree(osb, refcount_loc, 1,
5681 if (ret) { 5681 &ref_tree, NULL);
5682 mlog_errno(ret); 5682 if (ret) {
5683 goto bail; 5683 mlog_errno(ret);
5684 goto bail;
5685 }
5684 } 5686 }
5685 5687
5686 ret = ocfs2_prepare_refcount_change_for_del(inode, 5688 ret = ocfs2_prepare_refcount_change_for_del(inode,
@@ -7021,6 +7023,7 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb,
7021 u64 refcount_loc = le64_to_cpu(di->i_refcount_loc); 7023 u64 refcount_loc = le64_to_cpu(di->i_refcount_loc);
7022 struct ocfs2_extent_tree et; 7024 struct ocfs2_extent_tree et;
7023 struct ocfs2_cached_dealloc_ctxt dealloc; 7025 struct ocfs2_cached_dealloc_ctxt dealloc;
7026 struct ocfs2_refcount_tree *ref_tree = NULL;
7024 7027
7025 ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh); 7028 ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh);
7026 ocfs2_init_dealloc_ctxt(&dealloc); 7029 ocfs2_init_dealloc_ctxt(&dealloc);
@@ -7130,9 +7133,18 @@ start:
7130 7133
7131 phys_cpos = ocfs2_blocks_to_clusters(inode->i_sb, blkno); 7134 phys_cpos = ocfs2_blocks_to_clusters(inode->i_sb, blkno);
7132 7135
7136 if ((flags & OCFS2_EXT_REFCOUNTED) && trunc_len && !ref_tree) {
7137 status = ocfs2_lock_refcount_tree(osb, refcount_loc, 1,
7138 &ref_tree, NULL);
7139 if (status) {
7140 mlog_errno(status);
7141 goto bail;
7142 }
7143 }
7144
7133 status = ocfs2_remove_btree_range(inode, &et, trunc_cpos, 7145 status = ocfs2_remove_btree_range(inode, &et, trunc_cpos,
7134 phys_cpos, trunc_len, flags, &dealloc, 7146 phys_cpos, trunc_len, flags, &dealloc,
7135 refcount_loc); 7147 refcount_loc, true);
7136 if (status < 0) { 7148 if (status < 0) {
7137 mlog_errno(status); 7149 mlog_errno(status);
7138 goto bail; 7150 goto bail;
@@ -7147,6 +7159,8 @@ start:
7147 goto start; 7159 goto start;
7148 7160
7149bail: 7161bail:
7162 if (ref_tree)
7163 ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
7150 7164
7151 ocfs2_schedule_truncate_log_flush(osb, 1); 7165 ocfs2_schedule_truncate_log_flush(osb, 1);
7152 7166
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h
index ca381c584127..fb09b97db162 100644
--- a/fs/ocfs2/alloc.h
+++ b/fs/ocfs2/alloc.h
@@ -142,7 +142,7 @@ int ocfs2_remove_btree_range(struct inode *inode,
142 struct ocfs2_extent_tree *et, 142 struct ocfs2_extent_tree *et,
143 u32 cpos, u32 phys_cpos, u32 len, int flags, 143 u32 cpos, u32 phys_cpos, u32 len, int flags,
144 struct ocfs2_cached_dealloc_ctxt *dealloc, 144 struct ocfs2_cached_dealloc_ctxt *dealloc,
145 u64 refcount_loc); 145 u64 refcount_loc, bool refcount_tree_locked);
146 146
147int ocfs2_num_free_extents(struct ocfs2_super *osb, 147int ocfs2_num_free_extents(struct ocfs2_super *osb,
148 struct ocfs2_extent_tree *et); 148 struct ocfs2_extent_tree *et);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index d9f222987f24..46d93e941f3d 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -894,7 +894,7 @@ void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages)
894 } 894 }
895} 895}
896 896
897static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc) 897static void ocfs2_unlock_pages(struct ocfs2_write_ctxt *wc)
898{ 898{
899 int i; 899 int i;
900 900
@@ -915,7 +915,11 @@ static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
915 page_cache_release(wc->w_target_page); 915 page_cache_release(wc->w_target_page);
916 } 916 }
917 ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages); 917 ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages);
918}
918 919
920static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
921{
922 ocfs2_unlock_pages(wc);
919 brelse(wc->w_di_bh); 923 brelse(wc->w_di_bh);
920 kfree(wc); 924 kfree(wc);
921} 925}
@@ -2042,11 +2046,19 @@ out_write_size:
2042 ocfs2_update_inode_fsync_trans(handle, inode, 1); 2046 ocfs2_update_inode_fsync_trans(handle, inode, 1);
2043 ocfs2_journal_dirty(handle, wc->w_di_bh); 2047 ocfs2_journal_dirty(handle, wc->w_di_bh);
2044 2048
2049 /* unlock pages before dealloc since it needs acquiring j_trans_barrier
2050 * lock, or it will cause a deadlock since journal commit threads holds
2051 * this lock and will ask for the page lock when flushing the data.
2052 * put it here to preserve the unlock order.
2053 */
2054 ocfs2_unlock_pages(wc);
2055
2045 ocfs2_commit_trans(osb, handle); 2056 ocfs2_commit_trans(osb, handle);
2046 2057
2047 ocfs2_run_deallocs(osb, &wc->w_dealloc); 2058 ocfs2_run_deallocs(osb, &wc->w_dealloc);
2048 2059
2049 ocfs2_free_write_ctxt(wc); 2060 brelse(wc->w_di_bh);
2061 kfree(wc);
2050 2062
2051 return copied; 2063 return copied;
2052} 2064}
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 79d56dc981bc..319e786175af 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -4479,7 +4479,7 @@ int ocfs2_dx_dir_truncate(struct inode *dir, struct buffer_head *di_bh)
4479 p_cpos = ocfs2_blocks_to_clusters(dir->i_sb, blkno); 4479 p_cpos = ocfs2_blocks_to_clusters(dir->i_sb, blkno);
4480 4480
4481 ret = ocfs2_remove_btree_range(dir, &et, cpos, p_cpos, clen, 0, 4481 ret = ocfs2_remove_btree_range(dir, &et, cpos, p_cpos, clen, 0,
4482 &dealloc, 0); 4482 &dealloc, 0, false);
4483 if (ret) { 4483 if (ret) {
4484 mlog_errno(ret); 4484 mlog_errno(ret);
4485 goto out; 4485 goto out;
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 3689b3592042..a6944b25fd5b 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -695,14 +695,6 @@ void __dlm_lockres_grab_inflight_worker(struct dlm_ctxt *dlm,
695 res->inflight_assert_workers); 695 res->inflight_assert_workers);
696} 696}
697 697
698static void dlm_lockres_grab_inflight_worker(struct dlm_ctxt *dlm,
699 struct dlm_lock_resource *res)
700{
701 spin_lock(&res->spinlock);
702 __dlm_lockres_grab_inflight_worker(dlm, res);
703 spin_unlock(&res->spinlock);
704}
705
706static void __dlm_lockres_drop_inflight_worker(struct dlm_ctxt *dlm, 698static void __dlm_lockres_drop_inflight_worker(struct dlm_ctxt *dlm,
707 struct dlm_lock_resource *res) 699 struct dlm_lock_resource *res)
708{ 700{
@@ -1646,6 +1638,7 @@ send_response:
1646 } 1638 }
1647 mlog(0, "%u is the owner of %.*s, cleaning everyone else\n", 1639 mlog(0, "%u is the owner of %.*s, cleaning everyone else\n",
1648 dlm->node_num, res->lockname.len, res->lockname.name); 1640 dlm->node_num, res->lockname.len, res->lockname.name);
1641 spin_lock(&res->spinlock);
1649 ret = dlm_dispatch_assert_master(dlm, res, 0, request->node_idx, 1642 ret = dlm_dispatch_assert_master(dlm, res, 0, request->node_idx,
1650 DLM_ASSERT_MASTER_MLE_CLEANUP); 1643 DLM_ASSERT_MASTER_MLE_CLEANUP);
1651 if (ret < 0) { 1644 if (ret < 0) {
@@ -1653,7 +1646,8 @@ send_response:
1653 response = DLM_MASTER_RESP_ERROR; 1646 response = DLM_MASTER_RESP_ERROR;
1654 dlm_lockres_put(res); 1647 dlm_lockres_put(res);
1655 } else 1648 } else
1656 dlm_lockres_grab_inflight_worker(dlm, res); 1649 __dlm_lockres_grab_inflight_worker(dlm, res);
1650 spin_unlock(&res->spinlock);
1657 } else { 1651 } else {
1658 if (res) 1652 if (res)
1659 dlm_lockres_put(res); 1653 dlm_lockres_put(res);
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 69fb9f75b082..3950693dd0f6 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1803,7 +1803,7 @@ static int ocfs2_remove_inode_range(struct inode *inode,
1803 1803
1804 ret = ocfs2_remove_btree_range(inode, &et, trunc_cpos, 1804 ret = ocfs2_remove_btree_range(inode, &et, trunc_cpos,
1805 phys_cpos, trunc_len, flags, 1805 phys_cpos, trunc_len, flags,
1806 &dealloc, refcount_loc); 1806 &dealloc, refcount_loc, false);
1807 if (ret < 0) { 1807 if (ret < 0) {
1808 mlog_errno(ret); 1808 mlog_errno(ret);
1809 goto out; 1809 goto out;
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
index aa1eee06420f..d3ebf2e61853 100644
--- a/fs/proc/meminfo.c
+++ b/fs/proc/meminfo.c
@@ -12,6 +12,9 @@
12#include <linux/vmstat.h> 12#include <linux/vmstat.h>
13#include <linux/atomic.h> 13#include <linux/atomic.h>
14#include <linux/vmalloc.h> 14#include <linux/vmalloc.h>
15#ifdef CONFIG_CMA
16#include <linux/cma.h>
17#endif
15#include <asm/page.h> 18#include <asm/page.h>
16#include <asm/pgtable.h> 19#include <asm/pgtable.h>
17#include "internal.h" 20#include "internal.h"
@@ -138,6 +141,10 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
138#ifdef CONFIG_TRANSPARENT_HUGEPAGE 141#ifdef CONFIG_TRANSPARENT_HUGEPAGE
139 "AnonHugePages: %8lu kB\n" 142 "AnonHugePages: %8lu kB\n"
140#endif 143#endif
144#ifdef CONFIG_CMA
145 "CmaTotal: %8lu kB\n"
146 "CmaFree: %8lu kB\n"
147#endif
141 , 148 ,
142 K(i.totalram), 149 K(i.totalram),
143 K(i.freeram), 150 K(i.freeram),
@@ -187,12 +194,16 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
187 vmi.used >> 10, 194 vmi.used >> 10,
188 vmi.largest_chunk >> 10 195 vmi.largest_chunk >> 10
189#ifdef CONFIG_MEMORY_FAILURE 196#ifdef CONFIG_MEMORY_FAILURE
190 ,atomic_long_read(&num_poisoned_pages) << (PAGE_SHIFT - 10) 197 , atomic_long_read(&num_poisoned_pages) << (PAGE_SHIFT - 10)
191#endif 198#endif
192#ifdef CONFIG_TRANSPARENT_HUGEPAGE 199#ifdef CONFIG_TRANSPARENT_HUGEPAGE
193 ,K(global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * 200 , K(global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) *
194 HPAGE_PMD_NR) 201 HPAGE_PMD_NR)
195#endif 202#endif
203#ifdef CONFIG_CMA
204 , K(totalcma_pages)
205 , K(global_page_state(NR_FREE_CMA_PAGES))
206#endif
196 ); 207 );
197 208
198 hugetlb_report_meminfo(m); 209 hugetlb_report_meminfo(m);
diff --git a/include/linux/cma.h b/include/linux/cma.h
index a93438beb33c..9384ba66e975 100644
--- a/include/linux/cma.h
+++ b/include/linux/cma.h
@@ -15,6 +15,7 @@
15 15
16struct cma; 16struct cma;
17 17
18extern unsigned long totalcma_pages;
18extern phys_addr_t cma_get_base(struct cma *cma); 19extern phys_addr_t cma_get_base(struct cma *cma);
19extern unsigned long cma_get_size(struct cma *cma); 20extern unsigned long cma_get_size(struct cma *cma);
20 21
diff --git a/lib/show_mem.c b/lib/show_mem.c
index 5e256271b47b..7de89f4a36cf 100644
--- a/lib/show_mem.c
+++ b/lib/show_mem.c
@@ -8,6 +8,7 @@
8#include <linux/mm.h> 8#include <linux/mm.h>
9#include <linux/nmi.h> 9#include <linux/nmi.h>
10#include <linux/quicklist.h> 10#include <linux/quicklist.h>
11#include <linux/cma.h>
11 12
12void show_mem(unsigned int filter) 13void show_mem(unsigned int filter)
13{ 14{
@@ -38,7 +39,12 @@ void show_mem(unsigned int filter)
38 39
39 printk("%lu pages RAM\n", total); 40 printk("%lu pages RAM\n", total);
40 printk("%lu pages HighMem/MovableOnly\n", highmem); 41 printk("%lu pages HighMem/MovableOnly\n", highmem);
42#ifdef CONFIG_CMA
43 printk("%lu pages reserved\n", (reserved - totalcma_pages));
44 printk("%lu pages cma reserved\n", totalcma_pages);
45#else
41 printk("%lu pages reserved\n", reserved); 46 printk("%lu pages reserved\n", reserved);
47#endif
42#ifdef CONFIG_QUICKLIST 48#ifdef CONFIG_QUICKLIST
43 printk("%lu pages in pagetable cache\n", 49 printk("%lu pages in pagetable cache\n",
44 quicklist_total_size()); 50 quicklist_total_size());
diff --git a/mm/cma.c b/mm/cma.c
index f8917629cbdd..a85ae28709a3 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -337,6 +337,7 @@ int __init cma_declare_contiguous(phys_addr_t base,
337 if (ret) 337 if (ret)
338 goto err; 338 goto err;
339 339
340 totalcma_pages += (size / PAGE_SIZE);
340 pr_info("Reserved %ld MiB at %pa\n", (unsigned long)size / SZ_1M, 341 pr_info("Reserved %ld MiB at %pa\n", (unsigned long)size / SZ_1M,
341 &base); 342 &base);
342 return 0; 343 return 0;
diff --git a/mm/memory.c b/mm/memory.c
index 6efe36a998ba..d8aebc52265f 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2996,6 +2996,12 @@ static int do_shared_fault(struct mm_struct *mm, struct vm_area_struct *vma,
2996 2996
2997 if (set_page_dirty(fault_page)) 2997 if (set_page_dirty(fault_page))
2998 dirtied = 1; 2998 dirtied = 1;
2999 /*
3000 * Take a local copy of the address_space - page.mapping may be zeroed
3001 * by truncate after unlock_page(). The address_space itself remains
3002 * pinned by vma->vm_file's reference. We rely on unlock_page()'s
3003 * release semantics to prevent the compiler from undoing this copying.
3004 */
2999 mapping = fault_page->mapping; 3005 mapping = fault_page->mapping;
3000 unlock_page(fault_page); 3006 unlock_page(fault_page);
3001 if ((dirtied || vma->vm_ops->page_mkwrite) && mapping) { 3007 if ((dirtied || vma->vm_ops->page_mkwrite) && mapping) {
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index e58725aff7e9..f22c55947181 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -162,12 +162,6 @@ static const struct mempolicy_operations {
162 enum mpol_rebind_step step); 162 enum mpol_rebind_step step);
163} mpol_ops[MPOL_MAX]; 163} mpol_ops[MPOL_MAX];
164 164
165/* Check that the nodemask contains at least one populated zone */
166static int is_valid_nodemask(const nodemask_t *nodemask)
167{
168 return nodes_intersects(*nodemask, node_states[N_MEMORY]);
169}
170
171static inline int mpol_store_user_nodemask(const struct mempolicy *pol) 165static inline int mpol_store_user_nodemask(const struct mempolicy *pol)
172{ 166{
173 return pol->flags & MPOL_MODE_FLAGS; 167 return pol->flags & MPOL_MODE_FLAGS;
@@ -202,7 +196,7 @@ static int mpol_new_preferred(struct mempolicy *pol, const nodemask_t *nodes)
202 196
203static int mpol_new_bind(struct mempolicy *pol, const nodemask_t *nodes) 197static int mpol_new_bind(struct mempolicy *pol, const nodemask_t *nodes)
204{ 198{
205 if (!is_valid_nodemask(nodes)) 199 if (nodes_empty(*nodes))
206 return -EINVAL; 200 return -EINVAL;
207 pol->v.nodes = *nodes; 201 pol->v.nodes = *nodes;
208 return 0; 202 return 0;
@@ -234,7 +228,7 @@ static int mpol_set_nodemask(struct mempolicy *pol,
234 nodes = NULL; /* explicit local allocation */ 228 nodes = NULL; /* explicit local allocation */
235 else { 229 else {
236 if (pol->flags & MPOL_F_RELATIVE_NODES) 230 if (pol->flags & MPOL_F_RELATIVE_NODES)
237 mpol_relative_nodemask(&nsc->mask2, nodes,&nsc->mask1); 231 mpol_relative_nodemask(&nsc->mask2, nodes, &nsc->mask1);
238 else 232 else
239 nodes_and(nsc->mask2, *nodes, nsc->mask1); 233 nodes_and(nsc->mask2, *nodes, nsc->mask1);
240 234
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index fa974d87f60d..7633c503a116 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -111,6 +111,7 @@ static DEFINE_SPINLOCK(managed_page_count_lock);
111 111
112unsigned long totalram_pages __read_mostly; 112unsigned long totalram_pages __read_mostly;
113unsigned long totalreserve_pages __read_mostly; 113unsigned long totalreserve_pages __read_mostly;
114unsigned long totalcma_pages __read_mostly;
114/* 115/*
115 * When calculating the number of globally allowed dirty pages, there 116 * When calculating the number of globally allowed dirty pages, there
116 * is a certain number of per-zone reserves that should not be 117 * is a certain number of per-zone reserves that should not be
@@ -5586,7 +5587,7 @@ void __init mem_init_print_info(const char *str)
5586 5587
5587 pr_info("Memory: %luK/%luK available " 5588 pr_info("Memory: %luK/%luK available "
5588 "(%luK kernel code, %luK rwdata, %luK rodata, " 5589 "(%luK kernel code, %luK rwdata, %luK rodata, "
5589 "%luK init, %luK bss, %luK reserved" 5590 "%luK init, %luK bss, %luK reserved, %luK cma-reserved"
5590#ifdef CONFIG_HIGHMEM 5591#ifdef CONFIG_HIGHMEM
5591 ", %luK highmem" 5592 ", %luK highmem"
5592#endif 5593#endif
@@ -5594,7 +5595,8 @@ void __init mem_init_print_info(const char *str)
5594 nr_free_pages() << (PAGE_SHIFT-10), physpages << (PAGE_SHIFT-10), 5595 nr_free_pages() << (PAGE_SHIFT-10), physpages << (PAGE_SHIFT-10),
5595 codesize >> 10, datasize >> 10, rosize >> 10, 5596 codesize >> 10, datasize >> 10, rosize >> 10,
5596 (init_data_size + init_code_size) >> 10, bss_size >> 10, 5597 (init_data_size + init_code_size) >> 10, bss_size >> 10,
5597 (physpages - totalram_pages) << (PAGE_SHIFT-10), 5598 (physpages - totalram_pages - totalcma_pages) << (PAGE_SHIFT-10),
5599 totalcma_pages << (PAGE_SHIFT-10),
5598#ifdef CONFIG_HIGHMEM 5600#ifdef CONFIG_HIGHMEM
5599 totalhigh_pages << (PAGE_SHIFT-10), 5601 totalhigh_pages << (PAGE_SHIFT-10),
5600#endif 5602#endif
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 4d0a063145ec..b72403927aa4 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -884,19 +884,6 @@ static struct notifier_block zs_cpu_nb = {
884 .notifier_call = zs_cpu_notifier 884 .notifier_call = zs_cpu_notifier
885}; 885};
886 886
887static void zs_unregister_cpu_notifier(void)
888{
889 int cpu;
890
891 cpu_notifier_register_begin();
892
893 for_each_online_cpu(cpu)
894 zs_cpu_notifier(NULL, CPU_DEAD, (void *)(long)cpu);
895 __unregister_cpu_notifier(&zs_cpu_nb);
896
897 cpu_notifier_register_done();
898}
899
900static int zs_register_cpu_notifier(void) 887static int zs_register_cpu_notifier(void)
901{ 888{
902 int cpu, uninitialized_var(ret); 889 int cpu, uninitialized_var(ret);
@@ -914,40 +901,28 @@ static int zs_register_cpu_notifier(void)
914 return notifier_to_errno(ret); 901 return notifier_to_errno(ret);
915} 902}
916 903
917static void init_zs_size_classes(void) 904static void zs_unregister_cpu_notifier(void)
918{ 905{
919 int nr; 906 int cpu;
920 907
921 nr = (ZS_MAX_ALLOC_SIZE - ZS_MIN_ALLOC_SIZE) / ZS_SIZE_CLASS_DELTA + 1; 908 cpu_notifier_register_begin();
922 if ((ZS_MAX_ALLOC_SIZE - ZS_MIN_ALLOC_SIZE) % ZS_SIZE_CLASS_DELTA)
923 nr += 1;
924 909
925 zs_size_classes = nr; 910 for_each_online_cpu(cpu)
926} 911 zs_cpu_notifier(NULL, CPU_DEAD, (void *)(long)cpu);
912 __unregister_cpu_notifier(&zs_cpu_nb);
927 913
928static void __exit zs_exit(void) 914 cpu_notifier_register_done();
929{
930#ifdef CONFIG_ZPOOL
931 zpool_unregister_driver(&zs_zpool_driver);
932#endif
933 zs_unregister_cpu_notifier();
934} 915}
935 916
936static int __init zs_init(void) 917static void init_zs_size_classes(void)
937{ 918{
938 int ret = zs_register_cpu_notifier(); 919 int nr;
939
940 if (ret) {
941 zs_unregister_cpu_notifier();
942 return ret;
943 }
944 920
945 init_zs_size_classes(); 921 nr = (ZS_MAX_ALLOC_SIZE - ZS_MIN_ALLOC_SIZE) / ZS_SIZE_CLASS_DELTA + 1;
922 if ((ZS_MAX_ALLOC_SIZE - ZS_MIN_ALLOC_SIZE) % ZS_SIZE_CLASS_DELTA)
923 nr += 1;
946 924
947#ifdef CONFIG_ZPOOL 925 zs_size_classes = nr;
948 zpool_register_driver(&zs_zpool_driver);
949#endif
950 return 0;
951} 926}
952 927
953static unsigned int get_maxobj_per_zspage(int size, int pages_per_zspage) 928static unsigned int get_maxobj_per_zspage(int size, int pages_per_zspage)
@@ -967,113 +942,101 @@ static bool can_merge(struct size_class *prev, int size, int pages_per_zspage)
967 return true; 942 return true;
968} 943}
969 944
945unsigned long zs_get_total_pages(struct zs_pool *pool)
946{
947 return atomic_long_read(&pool->pages_allocated);
948}
949EXPORT_SYMBOL_GPL(zs_get_total_pages);
950
970/** 951/**
971 * zs_create_pool - Creates an allocation pool to work from. 952 * zs_map_object - get address of allocated object from handle.
972 * @flags: allocation flags used to allocate pool metadata 953 * @pool: pool from which the object was allocated
954 * @handle: handle returned from zs_malloc
973 * 955 *
974 * This function must be called before anything when using 956 * Before using an object allocated from zs_malloc, it must be mapped using
975 * the zsmalloc allocator. 957 * this function. When done with the object, it must be unmapped using
958 * zs_unmap_object.
976 * 959 *
977 * On success, a pointer to the newly created pool is returned, 960 * Only one object can be mapped per cpu at a time. There is no protection
978 * otherwise NULL. 961 * against nested mappings.
962 *
963 * This function returns with preemption and page faults disabled.
979 */ 964 */
980struct zs_pool *zs_create_pool(gfp_t flags) 965void *zs_map_object(struct zs_pool *pool, unsigned long handle,
966 enum zs_mapmode mm)
981{ 967{
982 int i; 968 struct page *page;
983 struct zs_pool *pool; 969 unsigned long obj_idx, off;
984 struct size_class *prev_class = NULL;
985 970
986 pool = kzalloc(sizeof(*pool), GFP_KERNEL); 971 unsigned int class_idx;
987 if (!pool) 972 enum fullness_group fg;
988 return NULL; 973 struct size_class *class;
974 struct mapping_area *area;
975 struct page *pages[2];
989 976
990 pool->size_class = kcalloc(zs_size_classes, sizeof(struct size_class *), 977 BUG_ON(!handle);
991 GFP_KERNEL);
992 if (!pool->size_class) {
993 kfree(pool);
994 return NULL;
995 }
996 978
997 /* 979 /*
998 * Iterate reversly, because, size of size_class that we want to use 980 * Because we use per-cpu mapping areas shared among the
999 * for merging should be larger or equal to current size. 981 * pools/users, we can't allow mapping in interrupt context
982 * because it can corrupt another users mappings.
1000 */ 983 */
1001 for (i = zs_size_classes - 1; i >= 0; i--) { 984 BUG_ON(in_interrupt());
1002 int size;
1003 int pages_per_zspage;
1004 struct size_class *class;
1005
1006 size = ZS_MIN_ALLOC_SIZE + i * ZS_SIZE_CLASS_DELTA;
1007 if (size > ZS_MAX_ALLOC_SIZE)
1008 size = ZS_MAX_ALLOC_SIZE;
1009 pages_per_zspage = get_pages_per_zspage(size);
1010
1011 /*
1012 * size_class is used for normal zsmalloc operation such
1013 * as alloc/free for that size. Although it is natural that we
1014 * have one size_class for each size, there is a chance that we
1015 * can get more memory utilization if we use one size_class for
1016 * many different sizes whose size_class have same
1017 * characteristics. So, we makes size_class point to
1018 * previous size_class if possible.
1019 */
1020 if (prev_class) {
1021 if (can_merge(prev_class, size, pages_per_zspage)) {
1022 pool->size_class[i] = prev_class;
1023 continue;
1024 }
1025 }
1026
1027 class = kzalloc(sizeof(struct size_class), GFP_KERNEL);
1028 if (!class)
1029 goto err;
1030 985
1031 class->size = size; 986 obj_handle_to_location(handle, &page, &obj_idx);
1032 class->index = i; 987 get_zspage_mapping(get_first_page(page), &class_idx, &fg);
1033 class->pages_per_zspage = pages_per_zspage; 988 class = pool->size_class[class_idx];
1034 spin_lock_init(&class->lock); 989 off = obj_idx_to_offset(page, obj_idx, class->size);
1035 pool->size_class[i] = class;
1036 990
1037 prev_class = class; 991 area = &get_cpu_var(zs_map_area);
992 area->vm_mm = mm;
993 if (off + class->size <= PAGE_SIZE) {
994 /* this object is contained entirely within a page */
995 area->vm_addr = kmap_atomic(page);
996 return area->vm_addr + off;
1038 } 997 }
1039 998
1040 pool->flags = flags; 999 /* this object spans two pages */
1041 1000 pages[0] = page;
1042 return pool; 1001 pages[1] = get_next_page(page);
1002 BUG_ON(!pages[1]);
1043 1003
1044err: 1004 return __zs_map_object(area, pages, off, class->size);
1045 zs_destroy_pool(pool);
1046 return NULL;
1047} 1005}
1048EXPORT_SYMBOL_GPL(zs_create_pool); 1006EXPORT_SYMBOL_GPL(zs_map_object);
1049 1007
1050void zs_destroy_pool(struct zs_pool *pool) 1008void zs_unmap_object(struct zs_pool *pool, unsigned long handle)
1051{ 1009{
1052 int i; 1010 struct page *page;
1011 unsigned long obj_idx, off;
1053 1012
1054 for (i = 0; i < zs_size_classes; i++) { 1013 unsigned int class_idx;
1055 int fg; 1014 enum fullness_group fg;
1056 struct size_class *class = pool->size_class[i]; 1015 struct size_class *class;
1016 struct mapping_area *area;
1057 1017
1058 if (!class) 1018 BUG_ON(!handle);
1059 continue;
1060 1019
1061 if (class->index != i) 1020 obj_handle_to_location(handle, &page, &obj_idx);
1062 continue; 1021 get_zspage_mapping(get_first_page(page), &class_idx, &fg);
1022 class = pool->size_class[class_idx];
1023 off = obj_idx_to_offset(page, obj_idx, class->size);
1063 1024
1064 for (fg = 0; fg < _ZS_NR_FULLNESS_GROUPS; fg++) { 1025 area = this_cpu_ptr(&zs_map_area);
1065 if (class->fullness_list[fg]) { 1026 if (off + class->size <= PAGE_SIZE)
1066 pr_info("Freeing non-empty class with size %db, fullness group %d\n", 1027 kunmap_atomic(area->vm_addr);
1067 class->size, fg); 1028 else {
1068 } 1029 struct page *pages[2];
1069 }
1070 kfree(class);
1071 }
1072 1030
1073 kfree(pool->size_class); 1031 pages[0] = page;
1074 kfree(pool); 1032 pages[1] = get_next_page(page);
1033 BUG_ON(!pages[1]);
1034
1035 __zs_unmap_object(area, pages, off, class->size);
1036 }
1037 put_cpu_var(zs_map_area);
1075} 1038}
1076EXPORT_SYMBOL_GPL(zs_destroy_pool); 1039EXPORT_SYMBOL_GPL(zs_unmap_object);
1077 1040
1078/** 1041/**
1079 * zs_malloc - Allocate block of given size from pool. 1042 * zs_malloc - Allocate block of given size from pool.
@@ -1176,100 +1139,137 @@ void zs_free(struct zs_pool *pool, unsigned long obj)
1176EXPORT_SYMBOL_GPL(zs_free); 1139EXPORT_SYMBOL_GPL(zs_free);
1177 1140
1178/** 1141/**
1179 * zs_map_object - get address of allocated object from handle. 1142 * zs_create_pool - Creates an allocation pool to work from.
1180 * @pool: pool from which the object was allocated 1143 * @flags: allocation flags used to allocate pool metadata
1181 * @handle: handle returned from zs_malloc
1182 *
1183 * Before using an object allocated from zs_malloc, it must be mapped using
1184 * this function. When done with the object, it must be unmapped using
1185 * zs_unmap_object.
1186 * 1144 *
1187 * Only one object can be mapped per cpu at a time. There is no protection 1145 * This function must be called before anything when using
1188 * against nested mappings. 1146 * the zsmalloc allocator.
1189 * 1147 *
1190 * This function returns with preemption and page faults disabled. 1148 * On success, a pointer to the newly created pool is returned,
1149 * otherwise NULL.
1191 */ 1150 */
1192void *zs_map_object(struct zs_pool *pool, unsigned long handle, 1151struct zs_pool *zs_create_pool(gfp_t flags)
1193 enum zs_mapmode mm)
1194{ 1152{
1195 struct page *page; 1153 int i;
1196 unsigned long obj_idx, off; 1154 struct zs_pool *pool;
1155 struct size_class *prev_class = NULL;
1197 1156
1198 unsigned int class_idx; 1157 pool = kzalloc(sizeof(*pool), GFP_KERNEL);
1199 enum fullness_group fg; 1158 if (!pool)
1200 struct size_class *class; 1159 return NULL;
1201 struct mapping_area *area;
1202 struct page *pages[2];
1203 1160
1204 BUG_ON(!handle); 1161 pool->size_class = kcalloc(zs_size_classes, sizeof(struct size_class *),
1162 GFP_KERNEL);
1163 if (!pool->size_class) {
1164 kfree(pool);
1165 return NULL;
1166 }
1205 1167
1206 /* 1168 /*
1207 * Because we use per-cpu mapping areas shared among the 1169 * Iterate reversly, because, size of size_class that we want to use
1208 * pools/users, we can't allow mapping in interrupt context 1170 * for merging should be larger or equal to current size.
1209 * because it can corrupt another users mappings.
1210 */ 1171 */
1211 BUG_ON(in_interrupt()); 1172 for (i = zs_size_classes - 1; i >= 0; i--) {
1173 int size;
1174 int pages_per_zspage;
1175 struct size_class *class;
1212 1176
1213 obj_handle_to_location(handle, &page, &obj_idx); 1177 size = ZS_MIN_ALLOC_SIZE + i * ZS_SIZE_CLASS_DELTA;
1214 get_zspage_mapping(get_first_page(page), &class_idx, &fg); 1178 if (size > ZS_MAX_ALLOC_SIZE)
1215 class = pool->size_class[class_idx]; 1179 size = ZS_MAX_ALLOC_SIZE;
1216 off = obj_idx_to_offset(page, obj_idx, class->size); 1180 pages_per_zspage = get_pages_per_zspage(size);
1217 1181
1218 area = &get_cpu_var(zs_map_area); 1182 /*
1219 area->vm_mm = mm; 1183 * size_class is used for normal zsmalloc operation such
1220 if (off + class->size <= PAGE_SIZE) { 1184 * as alloc/free for that size. Although it is natural that we
1221 /* this object is contained entirely within a page */ 1185 * have one size_class for each size, there is a chance that we
1222 area->vm_addr = kmap_atomic(page); 1186 * can get more memory utilization if we use one size_class for
1223 return area->vm_addr + off; 1187 * many different sizes whose size_class have same
1188 * characteristics. So, we makes size_class point to
1189 * previous size_class if possible.
1190 */
1191 if (prev_class) {
1192 if (can_merge(prev_class, size, pages_per_zspage)) {
1193 pool->size_class[i] = prev_class;
1194 continue;
1195 }
1196 }
1197
1198 class = kzalloc(sizeof(struct size_class), GFP_KERNEL);
1199 if (!class)
1200 goto err;
1201
1202 class->size = size;
1203 class->index = i;
1204 class->pages_per_zspage = pages_per_zspage;
1205 spin_lock_init(&class->lock);
1206 pool->size_class[i] = class;
1207
1208 prev_class = class;
1224 } 1209 }
1225 1210
1226 /* this object spans two pages */ 1211 pool->flags = flags;
1227 pages[0] = page;
1228 pages[1] = get_next_page(page);
1229 BUG_ON(!pages[1]);
1230 1212
1231 return __zs_map_object(area, pages, off, class->size); 1213 return pool;
1214
1215err:
1216 zs_destroy_pool(pool);
1217 return NULL;
1232} 1218}
1233EXPORT_SYMBOL_GPL(zs_map_object); 1219EXPORT_SYMBOL_GPL(zs_create_pool);
1234 1220
1235void zs_unmap_object(struct zs_pool *pool, unsigned long handle) 1221void zs_destroy_pool(struct zs_pool *pool)
1236{ 1222{
1237 struct page *page; 1223 int i;
1238 unsigned long obj_idx, off;
1239 1224
1240 unsigned int class_idx; 1225 for (i = 0; i < zs_size_classes; i++) {
1241 enum fullness_group fg; 1226 int fg;
1242 struct size_class *class; 1227 struct size_class *class = pool->size_class[i];
1243 struct mapping_area *area;
1244 1228
1245 BUG_ON(!handle); 1229 if (!class)
1230 continue;
1246 1231
1247 obj_handle_to_location(handle, &page, &obj_idx); 1232 if (class->index != i)
1248 get_zspage_mapping(get_first_page(page), &class_idx, &fg); 1233 continue;
1249 class = pool->size_class[class_idx];
1250 off = obj_idx_to_offset(page, obj_idx, class->size);
1251 1234
1252 area = this_cpu_ptr(&zs_map_area); 1235 for (fg = 0; fg < _ZS_NR_FULLNESS_GROUPS; fg++) {
1253 if (off + class->size <= PAGE_SIZE) 1236 if (class->fullness_list[fg]) {
1254 kunmap_atomic(area->vm_addr); 1237 pr_info("Freeing non-empty class with size %db, fullness group %d\n",
1255 else { 1238 class->size, fg);
1256 struct page *pages[2]; 1239 }
1240 }
1241 kfree(class);
1242 }
1257 1243
1258 pages[0] = page; 1244 kfree(pool->size_class);
1259 pages[1] = get_next_page(page); 1245 kfree(pool);
1260 BUG_ON(!pages[1]); 1246}
1247EXPORT_SYMBOL_GPL(zs_destroy_pool);
1261 1248
1262 __zs_unmap_object(area, pages, off, class->size); 1249static int __init zs_init(void)
1250{
1251 int ret = zs_register_cpu_notifier();
1252
1253 if (ret) {
1254 zs_unregister_cpu_notifier();
1255 return ret;
1263 } 1256 }
1264 put_cpu_var(zs_map_area); 1257
1258 init_zs_size_classes();
1259
1260#ifdef CONFIG_ZPOOL
1261 zpool_register_driver(&zs_zpool_driver);
1262#endif
1263 return 0;
1265} 1264}
1266EXPORT_SYMBOL_GPL(zs_unmap_object);
1267 1265
1268unsigned long zs_get_total_pages(struct zs_pool *pool) 1266static void __exit zs_exit(void)
1269{ 1267{
1270 return atomic_long_read(&pool->pages_allocated); 1268#ifdef CONFIG_ZPOOL
1269 zpool_unregister_driver(&zs_zpool_driver);
1270#endif
1271 zs_unregister_cpu_notifier();
1271} 1272}
1272EXPORT_SYMBOL_GPL(zs_get_total_pages);
1273 1273
1274module_init(zs_init); 1274module_init(zs_init);
1275module_exit(zs_exit); 1275module_exit(zs_exit);
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index b3831f4ba845..4e511221a0c1 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -1,22 +1,23 @@
1TARGETS = breakpoints 1TARGETS = breakpoints
2TARGETS += cpu-hotplug 2TARGETS += cpu-hotplug
3TARGETS += efivarfs 3TARGETS += efivarfs
4TARGETS += exec
5TARGETS += firmware
6TARGETS += ftrace
4TARGETS += kcmp 7TARGETS += kcmp
5TARGETS += memfd 8TARGETS += memfd
6TARGETS += memory-hotplug 9TARGETS += memory-hotplug
7TARGETS += mqueue
8TARGETS += mount 10TARGETS += mount
11TARGETS += mqueue
9TARGETS += net 12TARGETS += net
13TARGETS += powerpc
10TARGETS += ptrace 14TARGETS += ptrace
15TARGETS += size
16TARGETS += sysctl
11TARGETS += timers 17TARGETS += timers
12TARGETS += vm
13TARGETS += powerpc
14TARGETS += user 18TARGETS += user
15TARGETS += sysctl 19TARGETS += vm
16TARGETS += firmware 20#Please keep the TARGETS list alphabetically sorted
17TARGETS += ftrace
18TARGETS += exec
19TARGETS += size
20 21
21TARGETS_HOTPLUG = cpu-hotplug 22TARGETS_HOTPLUG = cpu-hotplug
22TARGETS_HOTPLUG += memory-hotplug 23TARGETS_HOTPLUG += memory-hotplug