How to configure Memory Windows
Contents
Abstract
- Running without memory windows, HP-UX has limitations for shared resources on 32-bit applications. All applications in the system are limited to a total of 1.75 GB of shared memory, 2.75 GB if compiled as SHMEM_MAGIC. In a system with 16 GB of physical memory, only 1.75 can be used for shared resources.
- To address this limitation, a functional change has been made to allow 32-bit processes to create unique memory windows for shared objects like shared memory.
- The memory window for default executables is 1 GB.
- This allows cooperating applications to create one GB of shared resources without exhausting the system-wide resource. Part of the virtual address space remains globally visible to all processes, so that shared libraries are accessible no matter what memory window they are in.
This article explains how to configure Memory Windows and at the same time demostrates the concept using the shmdemo program. This program allows to create or attached to a shared memory segment of 128 MB that can be used to test memory windows without the need of independent software applications.
Using shmdemo
Here is the ANSI C code for shmdemo. This 32 bit program uses a key file or an Id to create or attach to a Shared Memory Segment. When used with a Key file, the program stores the assigned segment key into the specified key file, that can be used on successive calls of the program to attached to the same segment. Likewise, manually provided the value stored in the key file will accomplish the same.
The programs traps TERM signal, [Ctrl-[c] or kill -s SIGINT to detach, remove the shared memory segment and close the program. This allows sending the program to the background as a job with a method to remove the shared memory segments when no more process are attached to it.
Source code:
/* This 32-bit program (shmdemo.c) creates or attaches to a 128 MB Shared Memory Segment (HP-UX). Was design to demostrate the workings of the Memory Windows feature on 64 bit kernels. It comes with no support and HP makes no representations as to its fitness for purpose. It is up to whoever uses this program to ensure that whatever functionality it provides is what they require. (c) Hewlett-Packard (2009) usage: shmdemo [-i id] | [-f keyfile] */ # include <stdio.h> # include <stdlib.h> # include <unistd.h> # include <signal.h> # include <strings.h> # include <sys/shm.h> # define MEMSIZE 128*1024*1024 # define MAXPATH 256 /* Public variable */ key_t key=0; int shmid; char *data; /* Prototypes */ int errors(int errorcode); void catch_int(int sig_num); int main(int argc, char** argv) { FILE *fp; int i; int n=0; char keyfile[MAXPATH]; char buffer[4096]; signal(SIGINT, catch_int); signal(SIGTERM, catch_int); /* Read command options */ for(i = 1; i < argc; i++) { if(argv[i][0] == '-') { switch (argv[i][1]) { case 'i': key = atoi(argv[i+1]); break; case 'f': strcpy(keyfile, argv[i+1]); break; default: return(errors(1)); } } } /* Verify that keyfile or Id are defined */ if(strlen(keyfile) < 1 && key == 0) return(errors(1)); /* If ID is not provided */ if(key == 0) { n = 1; if((fp = fopen(keyfile, "w")) == NULL) return(errors(2)); else { key = ftok(keyfile, 'R'); fprintf(fp, "%d\n", key); fclose(fp); } } if ((shmid = shmget(key, MEMSIZE, 0644 | IPC_CREAT)) == -1) { perror("shmget"); exit(1); } else { data = shmat(shmid, (void *)0, 0); if (data == (char *)(-1)) { perror("shmat"); exit(1); } } // Fills shared memory segment if Id was not provided if(n == 1) { for(i=0; i < 4096; i++) strcpy(buffer + i, "A"); } for(i=0; i < MEMSIZE / 4096 - 1; i++) strcpy(data + 4096*i, buffer); for( ; 1 > 0; ) sleep(30); } /* Error message handler */ int errors(int errorcode) { switch (errorcode) { case 1: fprintf(stderr, "ID or Keyfile not provided\n"); fprintf(stderr, "usage: shdemo [-i id] | [-f keyfile]\n"); break; case 2: fprintf(stderr, "Cannot open keyfile"); break; } return errorcode; } /* UNIX Signal handlers */ void catch_int(int sig_num) { signal(SIGINT, catch_int); /* Dettach from the segment */ fprintf(stderr, "Dettaching Shared Memory Segment... "); if (shmdt(data) == -1) { perror("shmdt"); } else printf("done.\n"); shmctl(shmid, IPC_RMID, NULL); exit(0); }
Compile:
# cc -O shmdemo.c -o shdemo
Executing shmdemo without Memory Windows
The following section show the how the program reacts on a system without Memory Windows. The ipcs command is used to demostrate the expected outputs.
# rm /tmp/*.key # ./shmdemo -f /tmp/shmdemo1.key & [1] 9903 # ipcs -mob IPC status from /dev/kmem as of Tue Sep 29 11:25:05 2009 T ID KEY MODE OWNER GROUP NATTCH SEGSZ Shared Memory: m 0 0x411c44da --rw-rw-rw- root root 0 348 m 1 0x4e0c0002 --rw-rw-rw- root root 1 61760 m 2 0x41270015 --rw-rw-rw- root root 1 8192 m 1245187 0x00000000 D-rw------- root sys 2 512000 m 4 0x02fb07f1 --rw------- hpsmdb users 8 10690560 m 5 0x06347849 --rw-rw-rw- root root 2 65544 m 6 0x0c6629c9 --rw-r----- root root 2 199169416 m 7 0x4918ecb0 --rw-r--r-- root root 0 22912 m 32776 0x00000000 D-rw------- root sys 2 2162688 m 32777 0x00000000 D-rw------- root sys 2 13360 m 1409034 0x52100008 --rw-r--r-- root sys 1 134217728 # cat /tmp/shmdemo1.key 1376780296
Note that the last shared memory segment has a single process attached (NATTCH) and it's size is 128 MB (SEGSZ)
# ./shmdemo -i `cat /tmp/shmdemo1.key` & [2] 9911 # ps -ef | grep /[s]hmdemo root 9933 9456 0 11:32:49 pts/tc 0:00 ./shmdemo -i 1376780296 root 9940 9456 0 11:32:55 pts/tc 0:00 ./shmdemo -i 1376780296 # ipcs -mob IPC status from /dev/kmem as of Tue Sep 29 11:27:41 2009 T ID KEY MODE OWNER GROUP NATTCH SEGSZ Shared Memory: m 0 0x411c44da --rw-rw-rw- root root 0 348 m 1 0x4e0c0002 --rw-rw-rw- root root 1 61760 m 2 0x41270015 --rw-rw-rw- root root 1 8192 m 1245187 0x00000000 D-rw------- root sys 2 512000 m 4 0x02fb07f1 --rw------- hpsmdb users 8 10690560 m 5 0x06347849 --rw-rw-rw- root root 2 65544 m 6 0x0c6629c9 --rw-r----- root root 2 199169416 m 7 0x4918ecb0 --rw-r--r-- root root 0 22912 m 32776 0x00000000 D-rw------- root sys 2 2162688 m 32777 0x00000000 D-rw------- root sys 2 13360 m 1409034 0x52100008 --rw-r--r-- root sys 2 134217728
- Note that two processes are attached (NATTCH) to the same shared memory segment.
Sending the signal TERM to each shmdemo process will close the application and release the shared memory segment.
# kill -s SIGINT 9940 9933 Dettaching Shared Memory Segment... done. Dettaching Shared Memory Segment... done. [2] + Done ./shmdemo -i `cat /tmp/shmdemo1.key` & [1] + Done ./shmdemo -i -f /tmp/shmdemo1.key & # ipcs -mob IPC status from /dev/kmem as of Tue Sep 29 11:33:59 2009 T ID KEY MODE OWNER GROUP NATTCH SEGSZ Shared Memory: m 0 0x411c44da --rw-rw-rw- root root 0 348 m 1 0x4e0c0002 --rw-rw-rw- root root 1 61760 m 2 0x41270015 --rw-rw-rw- root root 1 8192 m 1245187 0x00000000 D-rw------- root sys 2 512000 m 4 0x02fb07f1 --rw------- hpsmdb users 8 10690560 m 5 0x06347849 --rw-rw-rw- root root 2 65544 m 6 0x0c6629c9 --rw-r----- root root 2 199169416 m 7 0x4918ecb0 --rw-r--r-- root root 0 22912 m 32776 0x00000000 D-rw------- root sys 2 2162688 m 32777 0x00000000 D-rw------- root sys 2 13360
Executing shmdemo with Memory Windows
Enable Memory Windows
Set the max_mem_window kernel parameter to 2. This produces a total of three Memory Windows, the default (0) and two user-defined.
# kctune -s max_mem_window=2 ==> Update the automatic 'backup' configuration first? y * The automatic 'backup' configuration has been updated. * Future operations will update the backup without prompting. * The requested changes have been applied to the currently running configuration. Tunable Value Expression Changes max_mem_window (before) 0 Default Immed (now) 2 2
- Note: On HP-UX 11i v1, use kmtune or SAM to set max_mem_window kernel parameter. HP-UX 11i v2 and above use kctune, SAM, kcweb or System Management Homepage to set the values.
Edit /etc/services.window file
Below is a example /etc/services.window file.
# /etc/services.window # application1 20 application2 30
Test that the getmemwindow command returns the correct memory window identification number.
# getmemwindow application1 20 # getmemwindow application2 30
Start two instances of shmdemo on each Memory Window
# start_shmdemo.sh SHMDEMO=/tmp/shmdemo for count in 1 2 do setmemwindow -c -i `getmemwindow application$count` $SHMDEMO -f /tmp/application${count}.key & setmemwindow -j -i `getmemwindow application$count` $SHMDEMO -i $(cat /tmp/application${count}.key) & done
# sh /tmp/start_shmdemo.sh # ipcs -mob IPC status from /dev/kmem as of Wed Sep 30 18:11:16 2009 T ID KEY MODE OWNER GROUP NATTCH SEGSZ Shared Memory: m 0 0x411c44da --rw-rw-rw- root root 0 348 m 1 0x4e0c0002 --rw-rw-rw- root root 2 61760 m 2 0x412700a2 --rw-rw-rw- root root 1 8192 m 2457603 0x5210027c --rw-r--r-- root sys 2 134217728 m 1998852 0x00a5c581 --rw------- sfmdb users 8 10493952 m 5 0x02fb07f1 --rw------- hpsmdb users 1 10690560 m 6 0x06347849 --rw-rw-rw- root root 2 65544 m 7 0x0c6629c9 --rw-r----- root root 3 199169416 m 8 0x4918ecb0 --rw-r--r-- root root 0 22912 m 491529 0x5210027b --rw-r--r-- root sys 2 134217728
Observe that there are two 128 MB shared memory segments (2457603, 491529) each with two attached processes (NATTCH).
# ps -ef | grep /[s]hmdemo root 10114 10100 0 11:58:58 pts/tc 0:00 /tmp/shmdemo -f /tmp/application1.key root 10115 10104 0 11:58:58 pts/tc 0:00 /tmp/shmdemo -f /tmp/application2.key root 10100 1 0 11:58:58 pts/tc 0:00 setmemwindow -c -i 20 /tmp/shmdemo -f /tmp/application1.key root 10117 10102 0 11:58:58 pts/tc 0:00 /tmp/shmdemo -i 1376780302 root 10102 1 0 11:58:58 pts/tc 0:00 setmemwindow -j -i 20 /tmp/shmdemo -i 1376780302 root 10106 1 0 11:58:58 pts/tc 0:00 setmemwindow -j -i 30 /tmp/shmdemo -i 1376780303 root 10116 10106 0 11:58:58 pts/tc 0:00 /tmp/shmdemo -i 1376780303 root 10104 1 0 11:58:58 pts/tc 0:00 setmemwindow -c -i 30 /tmp/shmdemo -f /tmp/application2.key
The unsupported kmeminfo tool can be used to monitor the Memory Windows shared memory usage.
kmeminfo -window 20 tool: kmeminfo 9.10 - libp4 9.364 - libhpux 1.244 unix: /stand/current/vmunix 11.31 64bit PA2.0 on host "delta" core: /dev/kmem live link: Thu Sep 03 11:39:00 CST 2009 boot: Wed Sep 30 11:10:19 2009 time: Wed Sep 30 18:13:40 2009 nbpg: 4096 bytes Shared space from Window id 20: Space Start End Kbytes Usage Q2 0x01171c00.0x40000000-0x7fffffff 1048576 FREE Q2 Largest free segment ........... 1048576 ....... Q2 Total free space ............... 1048576 ....... Q3 0x08f46000.0x80000000-0x87ffffff 131072 SHMEM id=2457603 Q3 0x08f46000.0x88000000-0xbfffffff 917504 FREE Q3 Largest free segment ........... 917504 ....... Q3 Total free space ............... 917504 .......
# kmeminfo -window 30 tool: kmeminfo 9.10 - libp4 9.364 - libhpux 1.244 unix: /stand/current/vmunix 11.31 64bit PA2.0 on host "delta" core: /dev/kmem live link: Thu Sep 03 11:39:00 CST 2009 boot: Wed Sep 30 11:10:19 2009 time: Wed Sep 30 18:14:03 2009 nbpg: 4096 bytes Shared space from Window id 30: Space Start End Kbytes Usage Q2 0x0ba4a400.0x40000000-0x7fffffff 1048576 FREE Q2 Largest free segment ........... 1048576 ....... Q2 Total free space ............... 1048576 ....... Q3 0x03c46000.0x80000000-0x87ffffff 131072 SHMEM id=491529 Q3 0x03c46000.0x88000000-0xbfffffff 917504 FREE Q3 Largest free segment ........... 917504 ....... Q3 Total free space ............... 917504 .......
Note that shared memory segments are created on Q3 of the memory window. Each quadrant is made of 1 GB. The 128 MB shared memory segments assigned shdemo program is allocated on its respective Q3 quadrant.
Observe that there are (4) '/tmp/shmdemo process and (4) setmemwindow processes. To finish the program, sent the TERM or INT signal to the /tmp/shmdemo processes using the kill command.
# UNIX95= ps -eHf | grep /[s]hmdemo | sort -nk 2,2 root 17464 1 0 17:55:14 pts/0 00:00:00 setmemwindow -c -i 20 /tmp/shmdemo -f /tmp/application1.key root 17466 1 0 17:55:14 pts/0 00:00:00 setmemwindow -j -i 20 /tmp/shmdemo -i 1376780924 root 17469 1 0 17:55:14 pts/0 00:00:00 setmemwindow -c -i 30 /tmp/shmdemo -f /tmp/application2.key root 17471 1 0 17:55:14 pts/0 00:00:00 setmemwindow -j -i 30 /tmp/shmdemo -i 1376780923 root 17474 17464 0 17:55:14 pts/0 00:00:00 /tmp/shmdemo -f /tmp/application1.key root 17479 17469 0 17:55:14 pts/0 00:00:00 /tmp/shmdemo -f /tmp/application2.key root 17480 17466 0 17:55:14 pts/0 00:00:00 /tmp/shmdemo -i 1376780924 root 17481 17471 0 17:55:14 pts/0 00:00:00 /tmp/shmdemo -i 1376780923 # kill 17481 17480 17479 17474 # Dettaching Shared Memory Segment... done. Dettaching Shared Memory Segment... Dettaching Shared Memory Segment... done. Dettaching Shared Memory Segment... done. # ps -ef | grep /[s]hmdemo
Note that when all process are deattached from their respective Memory Window, the kmeminfo could not longer query the state of the memory window, because it does not longer exists!
# kmeminfo -window 20 tool: kmeminfo 9.10 - libp4 9.364 - libhpux 1.244 unix: /stand/current/vmunix 11.31 64bit PA2.0 on host "delta" core: /dev/kmem live link: Thu Sep 03 11:39:00 CST 2009 boot: Mon Sep 28 11:12:41 2009 time: Tue Sep 29 12:19:26 2009 nbpg: 4096 bytes Invalid memory window id !!!
# kmeminfo -window 30 tool: kmeminfo 9.10 - libp4 9.364 - libhpux 1.244 unix: /stand/current/vmunix 11.31 64bit PA2.0 on host "delta" core: /dev/kmem live link: Thu Sep 03 11:39:00 CST 2009 boot: Mon Sep 28 11:12:41 2009 time: Tue Sep 29 12:11:17 2009 nbpg: 4096 bytes
Reference
- Memory Windows White Paper / PDF
- Memory Windows - 11i v1 OLD LINK
- Memory Windows - 11i / PDF
- Memory Windows - 11.0 / PDF
- Using memory windows on HP-UX / PDF
Authors
- Alejandro Marin Badilla
- Editor : Scott Marer