Commit 1ab36c9d authored by Xiubo Li's avatar Xiubo Li Committed by Ilya Dryomov

ceph: allocate capsnap memory outside of ceph_queue_cap_snap()

This will reduce very possible but unnecessary frequently memory
allocate/free in this loop.

URL: https://tracker.ceph.com/issues/44100Signed-off-by: default avatarXiubo Li <xiubli@redhat.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 5ed91587
...@@ -522,23 +522,15 @@ static bool has_new_snaps(struct ceph_snap_context *o, ...@@ -522,23 +522,15 @@ static bool has_new_snaps(struct ceph_snap_context *o,
* Caller must hold snap_rwsem for read (i.e., the realm topology won't * Caller must hold snap_rwsem for read (i.e., the realm topology won't
* change). * change).
*/ */
static void ceph_queue_cap_snap(struct ceph_inode_info *ci) static void ceph_queue_cap_snap(struct ceph_inode_info *ci,
struct ceph_cap_snap **pcapsnap)
{ {
struct inode *inode = &ci->vfs_inode; struct inode *inode = &ci->vfs_inode;
struct ceph_cap_snap *capsnap;
struct ceph_snap_context *old_snapc, *new_snapc; struct ceph_snap_context *old_snapc, *new_snapc;
struct ceph_cap_snap *capsnap = *pcapsnap;
struct ceph_buffer *old_blob = NULL; struct ceph_buffer *old_blob = NULL;
int used, dirty; int used, dirty;
capsnap = kmem_cache_zalloc(ceph_cap_snap_cachep, GFP_NOFS);
if (!capsnap) {
pr_err("ENOMEM allocating ceph_cap_snap on %p\n", inode);
return;
}
capsnap->cap_flush.is_capsnap = true;
INIT_LIST_HEAD(&capsnap->cap_flush.i_list);
INIT_LIST_HEAD(&capsnap->cap_flush.g_list);
spin_lock(&ci->i_ceph_lock); spin_lock(&ci->i_ceph_lock);
used = __ceph_caps_used(ci); used = __ceph_caps_used(ci);
dirty = __ceph_caps_dirty(ci); dirty = __ceph_caps_dirty(ci);
...@@ -595,9 +587,6 @@ static void ceph_queue_cap_snap(struct ceph_inode_info *ci) ...@@ -595,9 +587,6 @@ static void ceph_queue_cap_snap(struct ceph_inode_info *ci)
capsnap->need_flush ? "" : "no_flush"); capsnap->need_flush ? "" : "no_flush");
ihold(inode); ihold(inode);
refcount_set(&capsnap->nref, 1);
INIT_LIST_HEAD(&capsnap->ci_item);
capsnap->follows = old_snapc->seq; capsnap->follows = old_snapc->seq;
capsnap->issued = __ceph_caps_issued(ci, NULL); capsnap->issued = __ceph_caps_issued(ci, NULL);
capsnap->dirty = dirty; capsnap->dirty = dirty;
...@@ -635,7 +624,7 @@ static void ceph_queue_cap_snap(struct ceph_inode_info *ci) ...@@ -635,7 +624,7 @@ static void ceph_queue_cap_snap(struct ceph_inode_info *ci)
/* note mtime, size NOW. */ /* note mtime, size NOW. */
__ceph_finish_cap_snap(ci, capsnap); __ceph_finish_cap_snap(ci, capsnap);
} }
capsnap = NULL; *pcapsnap = NULL;
old_snapc = NULL; old_snapc = NULL;
update_snapc: update_snapc:
...@@ -651,8 +640,6 @@ static void ceph_queue_cap_snap(struct ceph_inode_info *ci) ...@@ -651,8 +640,6 @@ static void ceph_queue_cap_snap(struct ceph_inode_info *ci)
spin_unlock(&ci->i_ceph_lock); spin_unlock(&ci->i_ceph_lock);
ceph_buffer_put(old_blob); ceph_buffer_put(old_blob);
if (capsnap)
kmem_cache_free(ceph_cap_snap_cachep, capsnap);
ceph_put_snap_context(old_snapc); ceph_put_snap_context(old_snapc);
} }
...@@ -720,6 +707,7 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm) ...@@ -720,6 +707,7 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm)
{ {
struct ceph_inode_info *ci; struct ceph_inode_info *ci;
struct inode *lastinode = NULL; struct inode *lastinode = NULL;
struct ceph_cap_snap *capsnap = NULL;
dout("queue_realm_cap_snaps %p %llx inodes\n", realm, realm->ino); dout("queue_realm_cap_snaps %p %llx inodes\n", realm, realm->ino);
...@@ -731,12 +719,34 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm) ...@@ -731,12 +719,34 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm)
spin_unlock(&realm->inodes_with_caps_lock); spin_unlock(&realm->inodes_with_caps_lock);
iput(lastinode); iput(lastinode);
lastinode = inode; lastinode = inode;
ceph_queue_cap_snap(ci);
/*
* Allocate the capsnap memory outside of ceph_queue_cap_snap()
* to reduce very possible but unnecessary frequently memory
* allocate/free in this loop.
*/
if (!capsnap) {
capsnap = kmem_cache_zalloc(ceph_cap_snap_cachep, GFP_NOFS);
if (!capsnap) {
pr_err("ENOMEM allocating ceph_cap_snap on %p\n",
inode);
return;
}
}
capsnap->cap_flush.is_capsnap = true;
refcount_set(&capsnap->nref, 1);
INIT_LIST_HEAD(&capsnap->cap_flush.i_list);
INIT_LIST_HEAD(&capsnap->cap_flush.g_list);
INIT_LIST_HEAD(&capsnap->ci_item);
ceph_queue_cap_snap(ci, &capsnap);
spin_lock(&realm->inodes_with_caps_lock); spin_lock(&realm->inodes_with_caps_lock);
} }
spin_unlock(&realm->inodes_with_caps_lock); spin_unlock(&realm->inodes_with_caps_lock);
iput(lastinode); iput(lastinode);
if (capsnap)
kmem_cache_free(ceph_cap_snap_cachep, capsnap);
dout("queue_realm_cap_snaps %p %llx done\n", realm, realm->ino); dout("queue_realm_cap_snaps %p %llx done\n", realm, realm->ino);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment