How to configure Memory Windows

From Wiki-UX.info
Jump to: navigation, search

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

Authors