OSDN Git Service

Remove canned_fs_config from ext4_utils
[android-x86/system-extras.git] / ksmutils / ksminfo.c
index ed311ac..278692f 100644 (file)
  */
 
 #include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <inttypes.h>
 #include <stdbool.h>
+#include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <getopt.h>
 
 #include <pagemap/pagemap.h>
 
@@ -43,6 +44,7 @@ struct vaddr {
 };
 
 struct ksm_page {
+    uint64_t count;
     uint32_t hash;
     struct vaddr *vaddr;
     size_t vaddr_len, vaddr_size;
@@ -187,7 +189,6 @@ exit:
 
 static int read_pages(struct ksm_pages *kp, pm_map_t **maps, size_t num_maps, uint8_t pr_flags) {
     size_t i, j, k;
-    size_t len;
     uint64_t *pagemap;
     size_t map_len;
     uint64_t flags;
@@ -234,9 +235,9 @@ static int read_pages(struct ksm_pages *kp, pm_map_t **maps, size_t num_maps, ui
             continue;
         }
         for (j = 0; j < map_len; j++) {
-            error = pm_kernel_flags(ker, pagemap[j], &flags);
+            error = pm_kernel_flags(ker, PM_PAGEMAP_PFN(pagemap[j]), &flags);
             if (error) {
-                fprintf(stderr, "warning: could not read flags for pfn at address 0x%016llx\n",
+                fprintf(stderr, "warning: could not read flags for pfn at address 0x%016" PRIx64 "\n",
                         pagemap[i]);
                 continue;
             }
@@ -249,7 +250,7 @@ static int read_pages(struct ksm_pages *kp, pm_map_t **maps, size_t num_maps, ui
                 fprintf(stderr, "warning: could not lseek to 0x%08lx\n", vaddr);
                 continue;
             }
-            len = read(fd, data, pm_kernel_pagesize(ker));
+            ssize_t len = read(fd, data, pm_kernel_pagesize(ker));
             if (len != pm_kernel_pagesize(ker)) {
                 fprintf(stderr, "warning: could not read page at 0x%08lx\n", vaddr);
                 continue;
@@ -275,6 +276,12 @@ static int read_pages(struct ksm_pages *kp, pm_map_t **maps, size_t num_maps, ui
                     kp->pages = tmp;
                     kp->size += GROWTH_FACTOR;
                 }
+                rc = pm_kernel_count(ker, PM_PAGEMAP_PFN(pagemap[j]), &kp->pages[kp->len].count);
+                if (rc) {
+                    fprintf(stderr, "error reading page count\n");
+                    free(pagemap);
+                    goto err_count;
+                }
                 kp->pages[kp->len].hash = hash;
                 kp->pages[kp->len].pattern =
                         is_pattern((uint8_t *)data, pm_kernel_pagesize(ker)) ?
@@ -318,6 +325,7 @@ static int read_pages(struct ksm_pages *kp, pm_map_t **maps, size_t num_maps, ui
     goto no_err;
 
 err_realloc:
+err_count:
     if (pr_flags & PR_VERBOSE) {
         for (i = 0; i < kp->len; i++) {
             free(kp->pages[i].vaddr);
@@ -343,10 +351,17 @@ static void print_pages(struct ksm_pages *kp, uint8_t pr_flags) {
         } else {
             printf("KSM CRC 0x%08x:", kp->pages[i].hash);
         }
-        printf(" %4d page", kp->pages[i].vaddr_count);
+        printf(" %4zu page", kp->pages[i].vaddr_count);
         if (kp->pages[i].vaddr_count > 1) {
             printf("s");
         }
+        if (!(pr_flags & PR_ALL)) {
+            printf(" (%" PRIu64 " reference", kp->pages[i].count);
+            if (kp->pages[i].count > 1) {
+                printf("s");
+            }
+            printf(")");
+        }
         printf("\n");
 
         if (pr_flags & PR_VERBOSE) {
@@ -356,7 +371,7 @@ static void print_pages(struct ksm_pages *kp, uint8_t pr_flags) {
                 for (k = 0; k < 8 && j < kp->pages[i].vaddr_len; k++, j++) {
                     printf(" 0x%08lx", kp->pages[i].vaddr[j].addr);
 
-                    index = snprintf(suffix, sizeof(suffix), ":%d",
+                    index = snprintf(suffix, sizeof(suffix), ":%zu",
                             kp->pages[i].vaddr[j].num_pages);
                     if (pr_flags & PR_ALL) {
                         index += snprintf(suffix + index, sizeof(suffix) - index, "[%d]",
@@ -393,8 +408,9 @@ static void usage(char *myname) {
 static int cmp_pages(const void *a, const void *b) {
     const struct ksm_page *pg_a = a;
     const struct ksm_page *pg_b = b;
+    int cmp = pg_b->vaddr_count - pg_a->vaddr_count;
 
-    return pg_b->vaddr_count - pg_a->vaddr_count;
+    return cmp ? cmp : pg_b->count - pg_a->count;
 }
 
 static bool is_pattern(uint8_t *data, size_t len) {
@@ -432,7 +448,7 @@ static int getprocname(pid_t pid, char *buf, int len) {
         return -1;
     }
 
-    if (asprintf(&filename, "/proc/%zd/cmdline", pid) < 0) {
+    if (asprintf(&filename, "/proc/%d/cmdline", (int)pid) < 0) {
         rc = 1;
         goto exit;
     }