max_map_count: corrected max_map_count condition

* kernel test for max_map_count_sysctl is:
   /* Too many mappings? */
   if (mm->map_count > sysctl_max_map_count)
     return -ENOMEM;
  so in LTP test map_count should be greater than max_map_count by 1

* only [vsyscall] is allocated without incrementing mm->map_count

Author: Bob Picco <bob.picco@oracle.com>

Signed-off-by: Stanislav kholmanskikh <stanislav.kholmanskikh@oracle.com>
Acked-by: Caspar Zhang <caspar@casparzhang.com>
Reviewed-by: Zhouping Liu <zliu@redhat.com>
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
diff --git a/testcases/kernel/mem/tunable/max_map_count.c b/testcases/kernel/mem/tunable/max_map_count.c
index e948868..01fbe5e 100644
--- a/testcases/kernel/mem/tunable/max_map_count.c
+++ b/testcases/kernel/mem/tunable/max_map_count.c
@@ -14,20 +14,16 @@
  * The program trys to invoke mmap() endless until triggering MAP_FAILED,
  * then read the process's maps file /proc/[pid]/maps, save the line number
  * to map_count variable, and compare it with /proc/sys/vm/max_map_count,
- * map_count should less than max_map_count.
- * Note: There are two special vmas VDSO and VSYSCALL, which are allocated
- * via install_special_mapping(), install_specail_mapping() allows the VMAs
- * to be allocated and inserted without checking the sysctl_map_map_count,
- * and each /proc/<pid>/maps has both at the end:
- * # cat /proc/self/maps
+ * map_count should be greater than max_map_count by 1;
+ *
+ * Note: On some architectures there is a special vma VSYSCALL, which
+ * is allocated without incrementing mm->map_count variable. On these
+ * architectures each /proc/<pid>/maps has at the end:
  * ...
  * ...
- * 7fff7b9ff000-7fff7ba00000 r-xp 00000000 00:00 0           [vdso]
  * ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0   [vsyscall]
  *
- * so during comparing with map_count and /proc/sys/vm/max_map_count,
- * we should except the two special vmas from map_count:
- * map_count -= 2;
+ * so we ignore this line during /proc/[pid]/maps reading.
  *
  * ********************************************************************
  * Copyright (C) 2012 Red Hat, Inc.
@@ -121,6 +117,21 @@
 	TEST_CLEANUP;
 }
 
+/* This is a filter to exclude map entries which aren't accounted
+ * for in the vm_area_struct's map_count.
+ */
+#if defined(__x86_64__) || defined(__x86__)
+static int filter_map(char *buf)
+{
+	return strcmp(buf, "[vsyscall]") == 0;
+}
+#else
+static int filter_map(char *buf)
+{
+	return 0;
+}
+#endif
+
 static long count_maps(pid_t pid)
 {
 	FILE *fp;
@@ -136,8 +147,7 @@
 	while (getline(&line, &len, fp) != -1) {
 		/* exclude vdso and vsyscall */
 		if (sscanf(line, "%*p-%*p %*4s %*p %*2d:%*2d %*d %s", buf) ==
-		    1 && ((strcmp(buf, "[vdso]") == 0) ||
-			  (strcmp(buf, "[vsyscall]") == 0)))
+				1 && filter_map(buf))
 			continue;
 		map_count++;
 	}
@@ -202,7 +212,12 @@
 			tst_brkm(TBROK, cleanup, "child did not stopped");
 
 		map_count = count_maps(pid);
-		if (map_count == max_maps)
+		/* Note max_maps will be exceeded by one for
+		 * the sysctl setting of max_map_count. This
+		 * is the mm failure point at the time of
+		 * writing this COMMENT!
+		*/
+		if (map_count == (max_maps + 1))
 			tst_resm(TPASS, "%ld map entries in total "
 				 "as expected.", max_maps);
 		else