From:Steve Adams
Date:04-Jul-2001 12:06
Subject:   SHMMAX and ISM on Solaris

Thanks to Suvamoy Sen and Harald van Breederode for pointing out a better way to use crash(1M) to determine if Solaris is using ISM for a particular shared memory segment. Apparently this technique is explained on page 435 of Jim Mauro's and Richard McDougall's Solaris Internals book.

Using this technique they have both demonstrated that ISM is indeed used for SGA's comprised of multiple shared memory segments. An extract of Suvamoy's proof is included below. Harald went further to demonstrate that "if the SGA is bigger than physical memory (a stupid thing to do of course) ... ISM is being used for those areas that fit into physical memory".

This is in regards to the Q+A on your web site regarding use of ISM on Sun Solaris when SGA is made up of multiple shared memory segments. To verify this I carried out the following tests:

I set SHMMAX intentionally to 64M on my server to force multiple shared memory segment allocations for a large SGA size. Next I started up an 8.1.6.2 database with an SGA size of 273M. This was the only database running. Next I used pmap to find out the attach addresses of these segments for a shadow process. For this purpose I chose a shadow process with unix pid 871.

oracle@vintage> /usr/proc/bin/pmap -x 871
871:    oraclecs01 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
Address   Kbytes Resident Shared Private Permissions       Mapped File
00010000   24712   11944    8200    3744 read/exec         oracle
01840000     232     232     168      64 read/write/exec   oracle
0187A000     280     272       -     272 read/write/exec    [ heap ]
20000000   52000   52000       -   52000 read/write/exec/shared  [shmid=0x2]
24000000   39008   39008       -   39008 read/write/exec/shared  [shmid=0x3]
27000000   58496   58496       -   58496 read/write/exec/shared  [shmid=0x4]
2B000000   58496   58496       -   58496 read/write/exec/shared  [shmid=0x5]
2F000000   53248   53248       -   53248 read/write/exec/shared  [shmid=0x6]
33000000   19704   19704       -   19704 read/write/exec/shared  [shmid=0x7]
80000000      72      72       -      72 read/write/exec/shared  [shmid=0x1]
EEDA0000      16      16      16       - read/exec         libc_psr.so.1
...
EFFF0000      64      64       -      64 read/write         [ stack ]
--------  ------  ------  ------  ------
total Kb  314984  297488   11136  286352

Next I used crash(1M) to investigate what memory driver is being used by this process for these shared memory regions. We see that this process occupies slot 61 in the process table. Next we use as -f to map the address space for this slot. (A small extract is given)

root@vintage> crash
dumpfile = /dev/mem, namelist = /dev/ksyms, outfile = stdout
> p
PROC TABLE SIZE = 7962
SLOT ST  PID  PPID  PGID   SID   UID PRI   NAME        FLAGS
   0 t     0     0     0     0     0  96 sched          load sys lock
   1 s     1     0     0     0     0  58 init           load
...
  59 s   794   395   794   794     0  53 in.telnetd     load
  60 s   918   653   918   918     0  58 hpapsadc       load
  61 s   871   870   871   871   560  42 oracle         load
  62 s   740     1   740   740     0  58 snmpdx         load nowait
  65 s   921   920   918   918     0  58 psar           load
...
> as -f 61
PROC        PAGLCK   CLGAP  VBITS HAT        HRM         RSS
 SEGLST     LOCK        SEGS       SIZE     LREP TAIL     NSEGS
  61        0        0      0x0   0x600e09c0   0x0
0x61b2a500  0xeffff4e8  0x61cd3d00  336764928  0     0x61cd39c0    53
 BASE        SIZE     AS       NEXT        PREV         OPS       DATA
0x00010000 1822000 0x60040730 0x61cd3ce0 0x00000000  segvn_ops 0x6114a6a0
0x01840000   3a000 0x60040730 0x61cd3c20 0x61cd3d00  segvn_ops 0x6114a3c8
0x0187a000   46000 0x60040730 0x61b2a520 0x61cd3ce0  segvn_ops 0x6114aeb8
0x20000000 3400000 0x60040730 0x61cd38a0 0x61cd3c20 segspt_shm 0x6115db60
0x24000000 2800000 0x60040730 0x61b2a080 0x61b2a520 segspt_shm 0x6115db40
0x27000000 3c00000 0x60040730 0x61cd3d20 0x61cd38a0 segspt_shm 0x6115db20
0x2b000000 3c00000 0x60040730 0x61cd3a40 0x61b2a080 segspt_shm 0x6115db00
0x2f000000 3400000 0x60040730 0x61cd3920 0x61cd3d20 segspt_shm 0x6115dae0
0x33000000 1400000 0x60040730 0x61b2a000 0x61cd3a40 segspt_shm 0x61a022a0
0x80000000  400000 0x60040730 0x61b2a380 0x61cd3920 segspt_shm 0x6115db80
0xeeda0000    4000 0x60040730 0x61cd3f00 0x61b2a000  segvn_ops 0x6114b0b0
0xeedb0000    4000 0x60040730 0x61cd3840 0x61b2a380  segvn_ops 0x6114b190
...

Again a small extract is given for the as -f listing. If we match up the BASE address in this output with the shared memory segment attach addresses in the pmap -x output and then look up the memory driver used by the kernel under the OPS column heading we see that all the shared memory segments are using the ISM driver segspt_shm to manage these memory regions, and hence using ISM. If ISM had not been used the driver used would have been segvn_ops. This method is described in the "Solaris Internals" book by Jim Mauro, etc. This conclusively establishes that even where the SGA in Oracle is split up into multiple shared memory segments, Solaris still uses ISM.

Thanks for bringing that to my attention. Working as root, one can check whether ISM is being used using the kmastat report within the crash utility. If the size of the sfmmu8_cache allocation increases linearly with the number of Oracle connections, then ISM is not being used.

As I understand it, ISM should work for an SGA comprised of multiple segments, but I've never tested it. In the absence of evidence to the contrary, I would be inclined to take Bob Sneed's word for it and keep using single segment SGAs. If anyone reading this is running a multiple segment SGA on Solaris (use ipcs -m to check) then it would be interesting if you could confirm whether ISM is in use or not.

With regard to your book quote...

"It is commonly suggested that the operating system limit on the size of a single shared memory segment should be raised in order to allow Oracle to allocate the SGA in a single shared memory segment if possible. I follow this advice, but for reasons of manageability. The performance difference is negligible at instance and process startup and is nil otherwise."
Similarly I have never noticed any difference in performance in the setting from SHMMAX, but recently in a Sun Blueprint by Bob Sneed, he seems to suggest some relationship between ISM and a single segment:
"For optimal Oracle performance, the SGA must be allocated in a single shared memory segment as ISM. If the SGA cannot be built this way, Oracle will use multiple segments, and will settle for non-ISM allocations."
Do you know if there is any truth to this? I don't have any idea how one would go about verifying it.