Re: shmget with SHM_HUGETLB flag: Operation not permitted

From: Jochen Roemling
Date: Sun Feb 29 2004 - 16:40:06 EST


William Lee Irwin III wrote:

It's capable(CAP_IPC_LOCK) || in_group_p(0), not current->uid == 0.
It will barf if you ask for more than either one of those limits. It
will also barf if you ask for an amount not a multiple of the hugepage
size. Please show the test program's code and strace the test program
to determine what response it's getting.



I attached the test pgm. It is nearly the same as shown
in Documentation/vm/hugetlbpage.txt

If you run it as root, it allocates 1 Hugepage, if run as user, it fails.

roesrv01:~ # ./a.out
shmid: 0x220004
shmaddr: 0x40167000
Starting the writes:
....
Starting the Check...Done.
roesrv01:~ # su - jochen
jochen@roesrv01:~> ./a.out
Failure:: Operation not permitted

I guess, a strace is not necessary.
The pgm has only the main function and only one position where it says "Failure"

What do I have to do to make this pgm run as an ordinary user with a stock kernel?

Curious...
Jochen
/* Example of using hugepage in user application using Sys V shared memory
* system calls. In this example, app is requesting memory of size 256MB that
* is backed by huge pages. Application uses the flag SHM_HUGETLB in shmget
* system call to informt the kernel that it is requesting hugepages. For
* IA-64 architecture, Linux kernel reserves Region number 4 for hugepages.
* That means the addresses starting with 0x800000....will need to be
* specified.
*/
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <errno.h>

extern int errno;
#define SHM_HUGETLB 04000
#define LPAGE_SIZE (4UL*1024UL*1024UL)
#define dprintf(x) printf(x)
#define ADDR (0x8000000000000000UL)
main()
{
int shmid;
int i, j, k;
volatile char *shmaddr;

if ((shmid =shmget(IPC_PRIVATE, LPAGE_SIZE, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W )) < 0) {
perror("Failure:");
exit(1);
}
printf("shmid: 0x%x\n", shmid);
shmaddr = shmat(shmid, (void *)ADDR, SHM_RND) ;
if (errno != 0) {
perror("Shared Memory Attach Failure:");
exit(2);
}
printf("shmaddr: %p\n", shmaddr);

dprintf("Starting the writes:\n");
for (i=0;i<LPAGE_SIZE;i++) {
shmaddr[i] = (char) (i);
if (!(i%(1024*1024))) dprintf(".");
}
dprintf("\n");
dprintf("Starting the Check...");
for (i=0; i<LPAGE_SIZE;i++)
if (shmaddr[i] != (char)i)
printf("\nIndex %d mismatched.");
dprintf("Done.\n");
if (shmdt((const void *)shmaddr) != 0) {
perror("Detached Failure:");
exit (3);
}
}