kernel - Implement segment pmap optimizations for x86-64 (1)
authorMatthew Dillon <dillon@apollo.backplane.com>
Thu, 13 Sep 2012 07:23:00 +0000 (00:23 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 13 Sep 2012 07:23:00 +0000 (00:23 -0700)
* Relax the mmap() size requirement when auto-aligning the address.
  Also auto-align to a segment boundary if the size is > 16 * SEG_SIZE.
  It previously only allowed size to be an exact multiple of SEG_SIZE.

* Some pages at the end won't be optimized, but the bulk of the mmap()
  will be.

sys/kern/tty_cons.c
sys/vm/vm_mmap.c

index cb9e2de..83774b8 100644 (file)
@@ -485,7 +485,7 @@ cngetc(void)
        int c;
        if ((cn_tab == NULL) || cn_mute)
                return (-1);
-       c = (*cn_tab->cn_getc)(cn_tab->cn_dev);
+       c = (*cn_tab->cn_getc)(cn_tab->cn_private);
        if (c == '\r') c = '\n'; /* console input is always ICRNL */
        return (c);
 }
@@ -495,7 +495,7 @@ cncheckc(void)
 {
        if ((cn_tab == NULL) || cn_mute)
                return (-1);
-       return ((*cn_tab->cn_checkc)(cn_tab->cn_dev));
+       return ((*cn_tab->cn_checkc)(cn_tab->cn_private));
 }
 
 void
@@ -507,21 +507,21 @@ cnputc(int c)
                return;
        if (c) {
                if (c == '\n')
-                       (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
-               (*cn_tab->cn_putc)(cn_tab->cn_dev, c);
+                       (*cn_tab->cn_putc)(cn_tab->cn_private, '\r');
+               (*cn_tab->cn_putc)(cn_tab->cn_private, c);
 #ifdef DDB
                if (console_pausing && !db_active && (c == '\n')) {
 #else
                if (console_pausing && (c == '\n')) {
 #endif
                        for(cp=console_pausestr; *cp != '\0'; cp++)
-                           (*cn_tab->cn_putc)(cn_tab->cn_dev, *cp);
+                           (*cn_tab->cn_putc)(cn_tab->cn_private, *cp);
                        if (cngetc() == '.')
                                console_pausing = 0;
-                       (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
+                       (*cn_tab->cn_putc)(cn_tab->cn_private, '\r');
                        for(cp=console_pausestr; *cp != '\0'; cp++)
-                           (*cn_tab->cn_putc)(cn_tab->cn_dev, ' ');
-                       (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
+                           (*cn_tab->cn_putc)(cn_tab->cn_private, ' ');
+                       (*cn_tab->cn_putc)(cn_tab->cn_private, '\r');
                }
        }
 }
@@ -536,7 +536,7 @@ cndbctl(int on)
        if (!on)
                refcount--;
        if (refcount == 0 && cn_tab->cn_dbctl != NULL)
-               (*cn_tab->cn_dbctl)(cn_tab->cn_dev, on);
+               (*cn_tab->cn_dbctl)(cn_tab->cn_private, on);
        if (on)
                refcount++;
 }
index d56c7d2..6c06a70 100644 (file)
@@ -1240,6 +1240,9 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
         * Handle alignment.  For large memory maps it is possible
         * that the MMU can optimize the page table so align anything
         * that is a multiple of SEG_SIZE to SEG_SIZE.
+        *
+        * Also align any large mapping (bigger than 16x SG_SIZE) to a
+        * SEG_SIZE address boundary.
         */
        if (flags & MAP_SIZEALIGN) {
                align = size;
@@ -1247,7 +1250,8 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
                        lwkt_reltoken(&map->token);
                        return (EINVAL);
                }
-       } else if ((flags & MAP_FIXED) == 0 && (size & SEG_MASK) == 0) {
+       } else if ((flags & MAP_FIXED) == 0 &&
+                  ((size & SEG_MASK) == 0 || size > SEG_SIZE * 16)) {
                align = SEG_SIZE;
        } else {
                align = PAGE_SIZE;