FBSD: Skip page flush in afs_DoPartialWrite 63/14163/6
authorAndrew Deason <adeason@dson.org>
Thu, 2 Jan 2020 02:11:35 +0000 (20:11 -0600)
committerBenjamin Kaduk <kaduk@mit.edu>
Thu, 2 Sep 2021 03:54:54 +0000 (23:54 -0400)
Currently, the FBSD afs_vop_putpages() will call afs_write(), which
can then go through afs_DoPartialWrite -> afs_StoreAllSegments ->
osi_VM_StoreAllSegments -> vm_object_page_clean, which will then try
to go through afs_vop_putpages() again.

In this call stack, we're only calling afs_StoreAllSegments to reduce
our dirty cache chunks (afs_StoreAllSegments does nothing if we don't
have that many dirty cache chunks); we don't need to reduce dirty
pages, so calling osi_VM_StoreAllSegments is not needed.

To avoid calling osi_VM_StoreAllSegments in this situation, add a new
flag AFS_NOVMSYNC, which skips the osi_VM_StoreAllSegments call and
just flushes the dirty cache chunks. Use this flag in
afs_DoPartialWrite on FBSD, and slightly refactor the ifdefs to reduce
some code duplication.

Change-Id: Id6bf9a7f4ac6d5f09b0249ca6ed11674d556e909
Reviewed-on: https://gerrit.openafs.org/14163
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>

src/afs/VNOPS/afs_vnop_write.c
src/afs/afs.h
src/afs/afs_segments.c

index cf8e334..a90118c 100644 (file)
@@ -433,6 +433,7 @@ int
 afs_DoPartialWrite(struct vcache *avc, struct vrequest *areq)
 {
     afs_int32 code;
+    int sync;
 
     if (afs_stats_cmperf.cacheCurrDirtyChunks <=
        afs_stats_cmperf.cacheMaxDirtyChunks
@@ -442,11 +443,13 @@ afs_DoPartialWrite(struct vcache *avc, struct vrequest *areq)
     afs_Trace2(afs_iclSetp, CM_TRACE_PARTIALWRITE, ICL_TYPE_POINTER, avc,
               ICL_TYPE_OFFSET, ICL_HANDLE_OFFSET(avc->f.m.Length));
 
+    sync = AFS_ASYNC;
 #if    defined(AFS_SUN5_ENV)
-    code = afs_StoreAllSegments(avc, areq, AFS_ASYNC | AFS_VMSYNC_INVAL);
-#else
-    code = afs_StoreAllSegments(avc, areq, AFS_ASYNC);
+    sync |= AFS_VMSYNC_INVAL;
+#elif defined(AFS_FBSD_ENV)
+    sync |= AFS_NOVMSYNC;
 #endif
+    code = afs_StoreAllSegments(avc, areq, sync);
     return code;
 }
 
index 013f9fb..c83f825 100644 (file)
@@ -152,6 +152,7 @@ struct sysname_info {
 #define AFS_VMSYNC_INVAL 2     /* sync and invalidate pages */
 #define AFS_LASTSTORE   4
 #define AFS_VMSYNC      8       /* sync pages but do not invalidate */
+#define AFS_NOVMSYNC    16      /* force skipping syncing vm pages; just write afs dcache data */
 
 /* background request structure */
 #define        BPARMS          4
index 7531723..2d79ef5 100644 (file)
@@ -185,7 +185,10 @@ afs_StoreAllSegments(struct vcache *avc, struct vrequest *areq,
      * on the memcache case since that's we adjust the file's size
      * and finish flushing partial vm pages.
      */
-    if ((cacheDiskType != AFS_FCACHE_TYPE_MEM) ||
+    if ((sync & AFS_NOVMSYNC)) {
+       /* noop */
+
+    } else if ((cacheDiskType != AFS_FCACHE_TYPE_MEM) ||
        (sync & AFS_VMSYNC_INVAL) || (sync & AFS_VMSYNC) ||
        (sync & AFS_LASTSTORE))
 #endif /* !AFS_AIX32_ENV && !AFS_SGI65_ENV */