diff --git a/mm/cma.c b/mm/cma.c
index 90e27458ddb7..08c45157911a 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -509,11 +509,11 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align,
 out:
 	if (page) {
 		count_vm_event(CMA_ALLOC_SUCCESS);
-		cma_sysfs_alloc_pages_count(cma, count);
+		cma_sysfs_account_success_pages(cma, count);
 	} else {
 		count_vm_event(CMA_ALLOC_FAIL);
 		if (cma)
-			cma_sysfs_fail_pages_count(cma, count);
+			cma_sysfs_account_fail_pages(cma, count);
 	}
 
 	return page;
diff --git a/mm/cma.h b/mm/cma.h
index 95d1aa2d808a..37b9b7858c8e 100644
--- a/mm/cma.h
+++ b/mm/cma.h
@@ -5,12 +5,8 @@
 #include <linux/debugfs.h>
 #include <linux/kobject.h>
 
-struct cma_stat {
-	spinlock_t lock;
-	/* the number of CMA page successful allocations */
-	unsigned long nr_pages_succeeded;
-	/* the number of CMA page allocation failures */
-	unsigned long nr_pages_failed;
+struct cma_kobject {
+	struct cma *cma;
 	struct kobject kobj;
 };
 
@@ -27,7 +23,12 @@ struct cma {
 #endif
 	char name[CMA_MAX_NAME];
 #ifdef CONFIG_CMA_SYSFS
-	struct cma_stat	*stat;
+	/* the number of CMA page successful allocations */
+	atomic64_t nr_pages_succeeded;
+	/* the number of CMA page allocation failures */
+	atomic64_t nr_pages_failed;
+	/* kobject requires dynamic object */
+	struct cma_kobject *cma_kobj;
 #endif
 };
 
@@ -40,10 +41,12 @@ static inline unsigned long cma_bitmap_maxno(struct cma *cma)
 }
 
 #ifdef CONFIG_CMA_SYSFS
-void cma_sysfs_alloc_pages_count(struct cma *cma, size_t count);
-void cma_sysfs_fail_pages_count(struct cma *cma, size_t count);
+void cma_sysfs_account_success_pages(struct cma *cma, unsigned long nr_pages);
+void cma_sysfs_account_fail_pages(struct cma *cma, unsigned long nr_pages);
 #else
-static inline void cma_sysfs_alloc_pages_count(struct cma *cma, size_t count) {};
-static inline void cma_sysfs_fail_pages_count(struct cma *cma, size_t count) {};
+static inline void cma_sysfs_account_success_pages(struct cma *cma,
+						   unsigned long nr_pages) {};
+static inline void cma_sysfs_account_fail_pages(struct cma *cma,
+						unsigned long nr_pages) {};
 #endif
 #endif
diff --git a/mm/cma_sysfs.c b/mm/cma_sysfs.c
index 3134b2b3a96d..a670a80aad6f 100644
--- a/mm/cma_sysfs.c
+++ b/mm/cma_sysfs.c
@@ -11,50 +11,54 @@
 
 #include "cma.h"
 
-static struct cma_stat *cma_stats;
-
-void cma_sysfs_alloc_pages_count(struct cma *cma, size_t count)
+void cma_sysfs_account_success_pages(struct cma *cma, unsigned long nr_pages)
 {
-	spin_lock(&cma->stat->lock);
-	cma->stat->nr_pages_succeeded += count;
-	spin_unlock(&cma->stat->lock);
+	atomic64_add(nr_pages, &cma->nr_pages_succeeded);
 }
 
-void cma_sysfs_fail_pages_count(struct cma *cma, size_t count)
+void cma_sysfs_account_fail_pages(struct cma *cma, unsigned long nr_pages)
 {
-	spin_lock(&cma->stat->lock);
-	cma->stat->nr_pages_failed += count;
-	spin_unlock(&cma->stat->lock);
+	atomic64_add(nr_pages, &cma->nr_pages_failed);
 }
 
 #define CMA_ATTR_RO(_name) \
 	static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
 
-static struct kobject *cma_kobj;
+static inline struct cma *cma_from_kobj(struct kobject *kobj)
+{
+	struct cma_kobject *cma_kobj = container_of(kobj, struct cma_kobject,
+						    kobj);
+	struct cma *cma = cma_kobj->cma;
+
+	return cma;
+}
 
 static ssize_t alloc_pages_success_show(struct kobject *kobj,
-			struct kobj_attribute *attr, char *buf)
+					struct kobj_attribute *attr, char *buf)
 {
-	struct cma_stat *stat = container_of(kobj, struct cma_stat, kobj);
+	struct cma *cma = cma_from_kobj(kobj);
 
-	return sysfs_emit(buf, "%lu\n", stat->nr_pages_succeeded);
+	return sysfs_emit(buf, "%llu\n",
+			atomic64_read(&cma->nr_pages_succeeded));
 }
 CMA_ATTR_RO(alloc_pages_success);
 
 static ssize_t alloc_pages_fail_show(struct kobject *kobj,
-			struct kobj_attribute *attr, char *buf)
+				     struct kobj_attribute *attr, char *buf)
 {
-	struct cma_stat *stat = container_of(kobj, struct cma_stat, kobj);
+	struct cma *cma = cma_from_kobj(kobj);
 
-	return sysfs_emit(buf, "%lu\n", stat->nr_pages_failed);
+	return sysfs_emit(buf, "%llu\n", atomic64_read(&cma->nr_pages_failed));
 }
 CMA_ATTR_RO(alloc_pages_fail);
 
 static void cma_kobj_release(struct kobject *kobj)
 {
-	struct cma_stat *stat = container_of(kobj, struct cma_stat, kobj);
+	struct cma *cma = cma_from_kobj(kobj);
+	struct cma_kobject *cma_kobj = cma->cma_kobj;
 
-	kfree(stat);
+	kfree(cma_kobj);
+	cma->cma_kobj = NULL;
 }
 
 static struct attribute *cma_attrs[] = {
@@ -67,44 +71,50 @@ ATTRIBUTE_GROUPS(cma);
 static struct kobj_type cma_ktype = {
 	.release = cma_kobj_release,
 	.sysfs_ops = &kobj_sysfs_ops,
-	.default_groups = cma_groups
+	.default_groups = cma_groups,
 };
 
 static int __init cma_sysfs_init(void)
 {
-	int i = 0;
+	struct kobject *cma_kobj_root;
+	struct cma_kobject *cma_kobj;
 	struct cma *cma;
+	unsigned int i;
+	int err;
 
-	cma_kobj = kobject_create_and_add("cma", mm_kobj);
-	if (!cma_kobj)
+	cma_kobj_root = kobject_create_and_add("cma", mm_kobj);
+	if (!cma_kobj_root)
 		return -ENOMEM;
 
-	cma_stats = kmalloc_array(cma_area_count, sizeof(struct cma_stat),
-				GFP_KERNEL|__GFP_ZERO);
-	if (ZERO_OR_NULL_PTR(cma_stats))
-		goto out;
+	for (i = 0; i < cma_area_count; i++) {
+		cma_kobj = kzalloc(sizeof(*cma_kobj), GFP_KERNEL);
+		if (!cma_kobj) {
+			err = -ENOMEM;
+			goto out;
+		}
 
-	do {
 		cma = &cma_areas[i];
-		cma->stat = &cma_stats[i];
-		spin_lock_init(&cma->stat->lock);
-		if (kobject_init_and_add(&cma->stat->kobj, &cma_ktype,
-					cma_kobj, "%s", cma->name)) {
-			kobject_put(&cma->stat->kobj);
+		cma->cma_kobj = cma_kobj;
+		cma_kobj->cma = cma;
+		err = kobject_init_and_add(&cma_kobj->kobj, &cma_ktype,
+				cma_kobj_root, "%s", cma->name);
+		if (err) {
+			kobject_put(&cma_kobj->kobj);
 			goto out;
 		}
-	} while (++i < cma_area_count);
+	}
 
 	return 0;
 out:
 	while (--i >= 0) {
 		cma = &cma_areas[i];
-		kobject_put(&cma->stat->kobj);
-	}
 
-	kfree(cma_stats);
-	kobject_put(cma_kobj);
+		kobject_put(&cma->cma_kobj->kobj);
+		kfree(cma->cma_kobj);
+		cma->cma_kobj = NULL;
+	}
+	kobject_put(cma_kobj_root);
 
-	return -ENOMEM;
+	return err;
 }
 subsys_initcall(cma_sysfs_init);
