@@ -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
641630update_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