shmmax tops out at 2G?

Bill Moran wmoran at collaborativefusion.com
Wed Dec 13 07:50:27 PST 2006


In response to Bill Moran <wmoran at collaborativefusion.com>:
> 
> [I sent this to questions@ yesterday and have yet to get a response.  I
> suspect it may be a little more technical than questions@]
> 
> uname -a
> FreeBSD db00.lab00 6.2-BETA3 FreeBSD 6.2-BETA3 #1: Fri Dec  8 09:27:37 EST 2006     root at db00.lab00:/usr/obj/usr/src/sys/DB-2850-amd64  amd64
> 
> sysctl kern.ipc.shmmax=2200000000
> kern.ipc.shmmax: 2100000000 -> -2094967296
> 
> Looks like an unsigned 32-bit int.  That doesn't seem to scale as well as
> would be expected on 64-bit arch (or PAE for that matter).
> 
> Is this a mistake, or intentional?  I'm working with some big memory
> systems, and I sure would like to allocate more than 2G for PostgreSQL
> to use ...

Responding/following up on my own post ...

Kris Kennaway <kris at obsecurity.org> wrote:
> Bill's guess is probably right, so someone needs to go over the sysv
> ipc code and make it 64-bit capable.

OK.  Looks like I've volunteered.  I know little to nothing about the
internals of the sysv system, so some of this may look pretty
uninformed.

First run through finds src/sys/sys/shm.h, which has a few obvious
data structures that need updated:

struct shmid_ds {
        struct ipc_perm shm_perm;       /* operation permission structure */
        int             shm_segsz;      /* size of segment in bytes */
        pid_t           shm_lpid;   /* process ID of last shared memory op */
        pid_t           shm_cpid;       /* process ID of creator */
        short           shm_nattch;     /* number of current attaches */
        time_t          shm_atime;      /* time of last shmat() */
        time_t          shm_dtime;      /* time of last shmdt() */
        time_t          shm_ctime;      /* time of last change by shmctl() */
        void           *shm_internal;   /* sysv stupidity */
};

struct shminfo {
        int     shmmax,         /* max shared memory segment size (bytes) */
                shmmin,         /* min shared memory segment size (bytes) */
                shmmni,         /* max number of shared memory identifiers */
                shmseg,         /* max shared memory segments per process */
                shmall;         /* max amount of shared memory (pages) */
};

However, looking at some function declarations in that same file:

int shmget(key_t, size_t, int);

I appears as if those values should have been size_t all along.  I'm
_assuming_ that the return value is an identifier and not a memory
address, which is what the docs seem to imply.

So, my first thought is that all the int values in those structures
should be changed to size_t.  If I understand the use of that type
correctly, it should always be the native word size on the architecture,
but will that make this work for PAE as well, or should those be
changed to uint64_t so they're 8 bits wide on all archs?

Once I understand a little more about what the correct type is for
those, I'll start looking for where they're used ...

-- 
Bill Moran
Collaborative Fusion Inc.

wmoran at collaborativefusion.com
Phone: 412-422-3463x4023


More information about the freebsd-hackers mailing list