xfs
[Top] [All Lists]

Re: memory leak when write in a file (with O_DIRECT flag).

To: Eric Sandeen <sandeen@xxxxxxx>
Subject: Re: memory leak when write in a file (with O_DIRECT flag).
From: Vincent Cassi <cassi@xxxxxxxxxx>
Date: Wed, 24 Jul 2002 13:00:13 -0600
Cc: "linux-xfs@xxxxxxxxxxx" <linux-xfs@xxxxxxxxxxx>
References: <3D2C4D10.C9F37CE9@vexcel.com> <1026314548.2644.14.camel@jen.americas.sgi.com> <3D3EC184.E53F3CAB@vexcel.com> <1027524227.23229.6.camel@stout.americas.sgi.com>
Sender: owner-linux-xfs@xxxxxxxxxxx
Eric Sandeen wrote:

> Hi Vincent -
>
> A couple more things, could you verify that you don't see this leak on,
> say, ext3 or some other filesystem?  Just to narrow it down to XFS.
>
> If you don't mind sharing your test program, I'd like to try to
> duplicate the problem here, when I get some time.
>
> Thanks,
>
> -Eric
>
> On Wed, 2002-07-24 at 10:02, Vincent Cassi wrote:
> > I did new tests with the kernel 2.4.19-rc1 and its corresponding XFS patch.
> > It looks like the memory leak is still there but a lot smaller.
> >
> > Thanks,
> > Vincent
> >
> >
> --
> Eric Sandeen      XFS for Linux    http://oss.sgi.com/projects/xfs
> sandeen@xxxxxxx   SGI, Inc.         651-683-3102

Hi Eric,

Here is the shell program which call the copy program (speed_w2f_block_leak):

j=0
while [ 1 ]
do
  printf "Repetition: %d \n" "${j}"
  cat /proc/meminfo
  sleep 5
  /utility/speed_w2f_block_leak 20 qq.out
  sleep 2
  cat /proc/meminfo
  printf "\n\n"
  let j=j+1
done

Attached is the copy program (speed_w2f_block_leak.c).

I built it with the following command:
gcc -D__KERNEL__ -DMODULE -I$(KERNEDIR)/include  -O  -Wall  -o
speed_w2f_block_leak speed_w2f_block_leak.c

Thanks,
Vincent

/*cs----------------------------------------------------------------------------
*
*
*       Module:         speed_w2f_block_leak.c
*
*       Purpose:        Calculate the speed for copying block of 4 Mbytes data
*                        to a file (using sgi XFS).
*                       Test leak memmory.
*
*       Comments:       
*
*       Arguments:      argv[1] = number of block.
*                       argv[2] = name of the file where the program write data.
*
*       Author:         Vincent Cassi
*
*       Date:           07.09.2002
*       
*       Revisions:
* 
* 
----------------------------------------------------------------------------ce*/

#define _GNU_SOURCE 

#include <stdlib.h>             /* exit, atoi, ... */
#include <stdio.h>              /* sprintf */
#include <unistd.h>             /* write */
#include <fcntl.h>              /* open */
#include <sys/ioctl.h>          /* ioctl */
#include <sys/time.h>           /* gettimeofday */
#include <sys/mman.h>           /* mlock */
#include <sys/stat.h>           /* S_IRUSR */

/* XFS */
#include <linux/xfs_fs.h>
#include <malloc.h>             /* memalign */


int main(int argc, char* argv[])
{
        dma_addr_t      *buffer_a = NULL;
        unsigned long   size;
        int             i,j;
        char            cursor;
        int             file_descriptor_w_0;
        int             error_write;
        int             write_count;
        struct timeval  st, et;
        struct timezone unused;
        float           elapsed_usec;
        float           megahertz;

        /* XFS */
        struct dioattr  dio;    
        int             error_dioinfo;

/*      Check number of arguments */
        if (argc != 3) {
                printf("!!! Wrong number of arguments !!!\n");
                printf("    Number of given arguments = %x\n", (argc - 1));
                printf("Give two arguments\n");
                printf("  The first argument is the number of block\n");
                printf("  The second argument is the name of the file\n");
                exit(-1);
        }

        size = atoi(argv[1]) * 4194304;
        
        printf("\nOpen file and write ...\n\n");

        write_count = 0;
        cursor = '\\';
        
/*
*       Open the file where the data have to be written
*/

        
        for(j = 0 ; j < 1 ; j++){
        
            /* Commit buffer cache to disk */
            /*sync();*/

            gettimeofday(&st, &unused);

            file_descriptor_w_0 = open64(argv[2],
                            O_WRONLY | O_CREAT | O_TRUNC | O_DIRECT ,
                                        S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
            if (file_descriptor_w_0 < 0) {
                perror(argv[2]);
                goto failed;
            }

            error_dioinfo = ioctl(file_descriptor_w_0, XFS_IOC_DIOINFO, &dio);
            if (error_dioinfo < 0) {
                perror("Dioinfo ");
                goto failed_buffer;
            }

            /* Get a buffer aligned the way we need it */
            buffer_a = memalign(dio.d_mem, size) ;
            if (!buffer_a) {
                perror("memalign");
                goto failed_buffer;
            }

            if (mlock(buffer_a, size)) {
                    perror("mlock");
                    goto failed_buffer;
            }
                                               
            /* Initialize and the buffer */
            for (i = 0; i < size / 4 ; i = i + 2) {
               buffer_a[i] = 0x000000fc;
               buffer_a[i + 1] = 0x0300fc03;
            }

            /* Write */
            error_write = write(file_descriptor_w_0,
                                        buffer_a, size);

            if(close(file_descriptor_w_0)) {
                perror("close");
                goto failed_buffer_lock;
            }

            gettimeofday(&et, &unused);
            elapsed_usec = (et.tv_sec * 1000000.0 + et.tv_usec) 
                                        - (st.tv_sec * 1000000.0 + st.tv_usec);
            megahertz = (size * 8) / elapsed_usec;
            
            if (error_write < 0) {
                    perror("write on file");
                    goto failed_buffer_lock;
            }
            printf("%c Write count: %10d %c\n",
                                cursor, error_write, cursor);

            write_count += error_write;
            
            printf(
            "%c %s Clock rate: %6.1f MHz, Data buffer alignment: %d, %d, %d  
%c\n",
                                cursor, argv[2] , megahertz, dio.d_mem,
                                        dio.d_miniosz, dio.d_maxiosz, cursor);
            cursor = cursor == '\\' ? '/' : '\\';
            if (munlock(buffer_a, size)) {
                    perror("munlock");
                    goto failed_buffer;
            }
            free(buffer_a);

        }
  

/*
*       Usual Output
*/
        exit(0);

/*
*       Failed Output
*/
failed_buffer_lock:
        munlock(buffer_a, size);        
failed_buffer:
        free(buffer_a);
failed:        
        /* Commit buffer cache to disk */
        /*sync();*/
                    
        exit(-1);
}




<Prev in Thread] Current Thread [Next in Thread>