Skip to content

Commit 1ab36c9

Browse files
lxbszidryomov
authored andcommitted
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/44100 Signed-off-by: Xiubo Li <xiubli@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
1 parent 5ed9158 commit 1ab36c9

1 file changed

Lines changed: 28 additions & 18 deletions

File tree

fs/ceph/snap.c

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -522,23 +522,15 @@ static bool has_new_snaps(struct ceph_snap_context *o,
522522
* Caller must hold snap_rwsem for read (i.e., the realm topology won't
523523
* change).
524524
*/
525-
static void ceph_queue_cap_snap(struct ceph_inode_info *ci)
525+
static void ceph_queue_cap_snap(struct ceph_inode_info *ci,
526+
struct ceph_cap_snap **pcapsnap)
526527
{
527528
struct inode *inode = &ci->vfs_inode;
528-
struct ceph_cap_snap *capsnap;
529529
struct ceph_snap_context *old_snapc, *new_snapc;
530+
struct ceph_cap_snap *capsnap = *pcapsnap;
530531
struct ceph_buffer *old_blob = NULL;
531532
int used, dirty;
532533

533-
capsnap = kmem_cache_zalloc(ceph_cap_snap_cachep, GFP_NOFS);
534-
if (!capsnap) {
535-
pr_err("ENOMEM allocating ceph_cap_snap on %p\n", inode);
536-
return;
537-
}
538-
capsnap->cap_flush.is_capsnap = true;
539-
INIT_LIST_HEAD(&capsnap->cap_flush.i_list);
540-
INIT_LIST_HEAD(&capsnap->cap_flush.g_list);
541-
542534
spin_lock(&ci->i_ceph_lock);
543535
used = __ceph_caps_used(ci);
544536
dirty = __ceph_caps_dirty(ci);
@@ -595,9 +587,6 @@ static void ceph_queue_cap_snap(struct ceph_inode_info *ci)
595587
capsnap->need_flush ? "" : "no_flush");
596588
ihold(inode);
597589

598-
refcount_set(&capsnap->nref, 1);
599-
INIT_LIST_HEAD(&capsnap->ci_item);
600-
601590
capsnap->follows = old_snapc->seq;
602591
capsnap->issued = __ceph_caps_issued(ci, NULL);
603592
capsnap->dirty = dirty;
@@ -635,7 +624,7 @@ static void ceph_queue_cap_snap(struct ceph_inode_info *ci)
635624
/* note mtime, size NOW. */
636625
__ceph_finish_cap_snap(ci, capsnap);
637626
}
638-
capsnap = NULL;
627+
*pcapsnap = NULL;
639628
old_snapc = NULL;
640629

641630
update_snapc:
@@ -651,8 +640,6 @@ static void ceph_queue_cap_snap(struct ceph_inode_info *ci)
651640
spin_unlock(&ci->i_ceph_lock);
652641

653642
ceph_buffer_put(old_blob);
654-
if (capsnap)
655-
kmem_cache_free(ceph_cap_snap_cachep, capsnap);
656643
ceph_put_snap_context(old_snapc);
657644
}
658645

@@ -720,6 +707,7 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm)
720707
{
721708
struct ceph_inode_info *ci;
722709
struct inode *lastinode = NULL;
710+
struct ceph_cap_snap *capsnap = NULL;
723711

724712
dout("queue_realm_cap_snaps %p %llx inodes\n", realm, realm->ino);
725713

@@ -731,12 +719,34 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm)
731719
spin_unlock(&realm->inodes_with_caps_lock);
732720
iput(lastinode);
733721
lastinode = inode;
734-
ceph_queue_cap_snap(ci);
722+
723+
/*
724+
* Allocate the capsnap memory outside of ceph_queue_cap_snap()
725+
* to reduce very possible but unnecessary frequently memory
726+
* allocate/free in this loop.
727+
*/
728+
if (!capsnap) {
729+
capsnap = kmem_cache_zalloc(ceph_cap_snap_cachep, GFP_NOFS);
730+
if (!capsnap) {
731+
pr_err("ENOMEM allocating ceph_cap_snap on %p\n",
732+
inode);
733+
return;
734+
}
735+
}
736+
capsnap->cap_flush.is_capsnap = true;
737+
refcount_set(&capsnap->nref, 1);
738+
INIT_LIST_HEAD(&capsnap->cap_flush.i_list);
739+
INIT_LIST_HEAD(&capsnap->cap_flush.g_list);
740+
INIT_LIST_HEAD(&capsnap->ci_item);
741+
742+
ceph_queue_cap_snap(ci, &capsnap);
735743
spin_lock(&realm->inodes_with_caps_lock);
736744
}
737745
spin_unlock(&realm->inodes_with_caps_lock);
738746
iput(lastinode);
739747

748+
if (capsnap)
749+
kmem_cache_free(ceph_cap_snap_cachep, capsnap);
740750
dout("queue_realm_cap_snaps %p %llx done\n", realm, realm->ino);
741751
}
742752

0 commit comments

Comments
 (0)