[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



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@sgi.com   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);
}