Bug 11758 - a program's data segment grows beyond RLIMIT_DATA limit set by setrlimit
Summary: a program's data segment grows beyond RLIMIT_DATA limit set by setrlimit
Status: CLOSED OBSOLETE
Alias: None
Product: Memory Management
Classification: Unclassified
Component: Other (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: Andrew Morton
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-10-14 07:01 UTC by L. Nieroda
Modified: 2012-05-14 16:50 UTC (History)
4 users (show)

See Also:
Kernel Version: 2.6.27
Subsystem:
Regression: No
Bisected commit-id:


Attachments
mmap.c class where we change rlimit data condition (67.79 KB, application/octet-stream)
2011-04-21 20:03 UTC, Waseem
Details
task_mmu.c for data limit (19.80 KB, application/octet-stream)
2011-04-21 20:04 UTC, Waseem
Details

Description L. Nieroda 2008-10-14 07:01:25 UTC
Latest working kernel version: N/A
Earliest failing kernel version: N/A
Distribution: Ubuntu
Hardware Environment: Intel CoreDuo E8400, 4 GB RAM
Software Environment: Ubuntu 8.04
Problem Description: I'm setting RLIMIT_DATA with the setrlimit system call and then proceed to allocate memory with malloc or "new" grossly above that limit, however, the memory is allocated and used without a problem. I've tried this with and without swap to make sure that the memory isn't allocated within it. The same check with RLIMIT_AS returns the expected result: memory allocation error. Am I missing something?

Steps to reproduce:
I've made a small c program to reproduce this behaviour:

---
#include <stdio.h>
#include <sys/resource.h>
#include <errno.h>


#define SOFT_LIMIT 100000
#define HARD_LIMIT 100000
#define ALLOCATED  150000

void check_rlimit(int resource) {
    char *data = NULL;
    struct rlimit rlp; 

    rlp.rlim_cur = SOFT_LIMIT; rlp.rlim_max=HARD_LIMIT;

    //setting the limits
    if (setrlimit(resource, &rlp) == -1) {
        perror("setrlimit");
        exit(1);
    }
    
    //check if limits are set
    if (getrlimit(resource, &rlp) == -1) {
      perror("getrlimit");
      exit(1);
    }

    printf("softlimit:  %d \n", rlp.rlim_cur); 
    printf("hardlimit:  %d \n", rlp.rlim_max); 

    fflush(stdout);
    
    //allocate over the limit
    printf("Allocating %d bytes.\n",ALLOCATED);
    data = (char *)malloc(ALLOCATED);
    if (data == NULL) {
      //printf("malloc failed with errno=%d\n", errno);
      perror("malloc");
      exit(1);
    }
    free(data);
}

int main(int argc, char *argv[]) {

  check_rlimit(RLIMIT_DATA);
  check_rlimit(RLIMIT_AS);

  return 0;
  exit(0);
}
---

The output is:
softlimit:  100000 
hardlimit:  100000 
Allocating 150000 bytes.
softlimit:  100000 
hardlimit:  100000 
Allocating 150000 bytes.
malloc: Cannot allocate memory

Any ideas?

Regards,
Lech Nieroda
Comment 1 david chosrova 2008-11-16 10:19:03 UTC
(In reply to comment #0)

I found this, it might help http://marc.info/?l=linux-kernel&m=118064795330579&w=2


> Latest working kernel version: N/A
> Earliest failing kernel version: N/A
> Distribution: Ubuntu
> Hardware Environment: Intel CoreDuo E8400, 4 GB RAM
> Software Environment: Ubuntu 8.04
> Problem Description: I'm setting RLIMIT_DATA with the setrlimit system call
> and
> then proceed to allocate memory with malloc or "new" grossly above that
> limit,
> however, the memory is allocated and used without a problem. I've tried this
> with and without swap to make sure that the memory isn't allocated within it.
> The same check with RLIMIT_AS returns the expected result: memory allocation
> error. Am I missing something?
> 
> Steps to reproduce:
> I've made a small c program to reproduce this behaviour:
> 
> ---
> #include <stdio.h>
> #include <sys/resource.h>
> #include <errno.h>
> 
> 
> #define SOFT_LIMIT 100000
> #define HARD_LIMIT 100000
> #define ALLOCATED  150000
> 
> void check_rlimit(int resource) {
>     char *data = NULL;
>     struct rlimit rlp; 
> 
>     rlp.rlim_cur = SOFT_LIMIT; rlp.rlim_max=HARD_LIMIT;
> 
>     //setting the limits
>     if (setrlimit(resource, &rlp) == -1) {
>         perror("setrlimit");
>         exit(1);
>     }
> 
>     //check if limits are set
>     if (getrlimit(resource, &rlp) == -1) {
>       perror("getrlimit");
>       exit(1);
>     }
> 
>     printf("softlimit:  %d \n", rlp.rlim_cur); 
>     printf("hardlimit:  %d \n", rlp.rlim_max); 
> 
>     fflush(stdout);
> 
>     //allocate over the limit
>     printf("Allocating %d bytes.\n",ALLOCATED);
>     data = (char *)malloc(ALLOCATED);
>     if (data == NULL) {
>       //printf("malloc failed with errno=%d\n", errno);
>       perror("malloc");
>       exit(1);
>     }
>     free(data);
> }
> 
> int main(int argc, char *argv[]) {
> 
>   check_rlimit(RLIMIT_DATA);
>   check_rlimit(RLIMIT_AS);
> 
>   return 0;
>   exit(0);
> }
> ---
> 
> The output is:
> softlimit:  100000 
> hardlimit:  100000 
> Allocating 150000 bytes.
> softlimit:  100000 
> hardlimit:  100000 
> Allocating 150000 bytes.
> malloc: Cannot allocate memory
> 
> Any ideas?
> 
> Regards,
> Lech Nieroda
> 
Comment 2 Matt McCutchen 2010-03-09 22:46:04 UTC
Yep, when brk fails because of RLIMIT_DATA, glibc switches to anonymous mmap instead.

https://bugzilla.redhat.com/show_bug.cgi?id=569714
http://lists.fedoraproject.org/pipermail/users/2010-March/368014.html
Comment 3 David Chin 2010-10-18 21:13:49 UTC
Same issue (reported by Matt McCutchen) being tracked on Fedora/RedHat's bugzilla:

https://bugzilla.redhat.com/show_bug.cgi?id=582072
Comment 4 Waseem 2011-04-21 20:03:28 UTC
Created attachment 54912 [details]
mmap.c class where we change rlimit data condition

Hi,

Yes We got same issue on linux kernel 2.6.32.29. We identified solution by doing some changes in files: mmap.c and task_mmu.c which are attached here. Basically we modify conditions regarding private memory of process(rlimit). We shall upload patch soon. Please find attached file, you can replace these files and compile your kernel and once you done it will will not show you this  bug any more.

Thanks

Waseem Hassan 
Saad Waqas
Comment 5 Waseem 2011-04-21 20:04:21 UTC
Created attachment 54922 [details]
task_mmu.c for data limit
Comment 6 Andrew Morton 2011-04-21 20:12:28 UTC
Yes, we'd need to see the patch, not the whole files.

Please send the patch via email, not via bugzilla.  Send it as a proper patch as per Documentation/SubmittingPatches.  Send it to

Andrew Morton <akpm@linux-foundation.org>, linux-mm@kvack.org

Thanks.

Note You need to log in before you can comment on or make changes to this bug.