changeset 4902:d463935e82be

6575117 3.59% snv_67 oltpnet_10g_raw performance regression x64 6591195 segvn_init() may return before checking HAT_SHARED_REGIONS support 6591891 segvn_textrepl() should use AT_CTIME | AT_MTIME to check file modification date
author paulsan
date Mon, 20 Aug 2007 07:59:23 -0700
parents e5be9002831f
children 367557499636
files usr/src/uts/common/vm/seg_vn.c usr/src/uts/common/vm/seg_vn.h
diffstat 2 files changed, 36 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/vm/seg_vn.c	Mon Aug 20 03:56:52 2007 -0700
+++ b/usr/src/uts/common/vm/seg_vn.c	Mon Aug 20 07:59:23 2007 -0700
@@ -358,7 +358,7 @@
 static svntr_stats_t		*segvn_textrepl_stats;
 static ksema_t 			segvn_trasync_sem;
 
-int				segvn_disable_textrepl = 0;
+int				segvn_disable_textrepl = 1;
 size_t				textrepl_size_thresh = (size_t)-1;
 size_t				segvn_textrepl_bytes = 0;
 size_t				segvn_textrepl_max_bytes = 0;
@@ -390,27 +390,26 @@
 		segvn_cache_constructor, segvn_cache_destructor, NULL,
 		NULL, NULL, 0);
 
-	if (segvn_lpg_disable != 0)
-		return;
-	szc = maxszc = page_num_pagesizes() - 1;
-	if (szc == 0) {
-		segvn_lpg_disable = 1;
-		return;
-	}
-	if (page_get_pagesize(0) != PAGESIZE) {
-		panic("segvn_init: bad szc 0");
-		/*NOTREACHED*/
-	}
-	while (szc != 0) {
-		pgsz = page_get_pagesize(szc);
-		if (pgsz <= PAGESIZE || !IS_P2ALIGNED(pgsz, pgsz)) {
-			panic("segvn_init: bad szc %d", szc);
+	if (segvn_lpg_disable == 0) {
+		szc = maxszc = page_num_pagesizes() - 1;
+		if (szc == 0) {
+			segvn_lpg_disable = 1;
+		}
+		if (page_get_pagesize(0) != PAGESIZE) {
+			panic("segvn_init: bad szc 0");
 			/*NOTREACHED*/
 		}
-		szc--;
-	}
-	if (segvn_maxpgszc == 0 || segvn_maxpgszc > maxszc)
-		segvn_maxpgszc = maxszc;
+		while (szc != 0) {
+			pgsz = page_get_pagesize(szc);
+			if (pgsz <= PAGESIZE || !IS_P2ALIGNED(pgsz, pgsz)) {
+				panic("segvn_init: bad szc %d", szc);
+				/*NOTREACHED*/
+			}
+			szc--;
+		}
+		if (segvn_maxpgszc == 0 || segvn_maxpgszc > maxszc)
+			segvn_maxpgszc = maxszc;
+	}
 
 	if (segvn_use_regions && !hat_supported(HAT_SHARED_REGIONS, NULL))
 		segvn_use_regions = 0;
@@ -9003,7 +9002,7 @@
 	 * Avoid creating anon maps with size bigger than the file size.
 	 * If VOP_GETATTR() call fails bail out.
 	 */
-	va.va_mask = AT_SIZE | AT_MTIME;
+	va.va_mask = AT_SIZE | AT_MTIME | AT_CTIME;
 	if (VOP_GETATTR(vp, &va, 0, svd->cred) != 0) {
 		svd->tr_state = SEGVN_TR_OFF;
 		SEGVN_TR_ADDSTAT(gaerr);
@@ -9045,13 +9044,24 @@
 		if (svntrp->tr_vp != vp) {
 			continue;
 		}
+
 		/*
-		 * Bail out if file was changed after this replication entry
-		 * was created since we need to use the latest file contents.
+		 * Bail out if the file or its attributes were changed after
+		 * this replication entry was created since we need to use the
+		 * latest file contents. Note that mtime test alone is not
+		 * sufficient because a user can explicitly change mtime via
+		 * utimes(2) interfaces back to the old value after modifiying
+		 * the file contents. To detect this case we also have to test
+		 * ctime which among other things records the time of the last
+		 * mtime change by utimes(2). ctime is not changed when the file
+		 * is only read or executed so we expect that typically existing
+		 * replication amp's can be used most of the time.
 		 */
 		if (!svntrp->tr_valid ||
 		    svntrp->tr_mtime.tv_sec != va.va_mtime.tv_sec ||
-		    svntrp->tr_mtime.tv_nsec != va.va_mtime.tv_nsec) {
+		    svntrp->tr_mtime.tv_nsec != va.va_mtime.tv_nsec ||
+		    svntrp->tr_ctime.tv_sec != va.va_ctime.tv_sec ||
+		    svntrp->tr_ctime.tv_nsec != va.va_ctime.tv_nsec) {
 			mutex_exit(&svntr_hashtab[hash].tr_lock);
 			svd->tr_state = SEGVN_TR_OFF;
 			SEGVN_TR_ADDSTAT(stale);
@@ -9103,6 +9113,7 @@
 		svntrp->tr_szc = szc;
 		svntrp->tr_valid = 1;
 		svntrp->tr_mtime = va.va_mtime;
+		svntrp->tr_ctime = va.va_ctime;
 		svntrp->tr_refcnt = 0;
 		svntrp->tr_next = svntr_hashtab[hash].tr_head;
 		svntr_hashtab[hash].tr_head = svntrp;
--- a/usr/src/uts/common/vm/seg_vn.h	Mon Aug 20 03:56:52 2007 -0700
+++ b/usr/src/uts/common/vm/seg_vn.h	Mon Aug 20 07:59:23 2007 -0700
@@ -184,6 +184,7 @@
 	int		tr_valid;	/* entry validity state */
 	struct svntr	*tr_next;	/* next svntr in this hash bucket */
 	timestruc_t	tr_mtime;	/* tr_vp modification time */
+	timestruc_t	tr_ctime;	/* time of last change to attributes */
 	ulong_t		tr_refcnt;	/* number of segs sharing this entry */
 	segvn_data_t	*tr_svnhead;	/* list of segs sharing this entry */
 	struct anon_map	*tr_amp[NLGRPS_MAX]; /* per lgrp anon maps */