NFS Performance

Till Straumann strauman at slac.stanford.edu
Mon Sep 18 17:56:43 UTC 2006


Let me first thank Steven for bringing this issue to our attention and
for testing the proposed fix and for providing patches.

Eric Norum wrote:
> I'd like to state my objection to this.   
> I don't think that it's a good idea to have an API with different 
> arguments to the same function.
I agree.
>
> May I suggest instead that:
> 1) All the ifdefs be removed fromt the nfs code.
Yes. Note that there is no need to test for HAVE_BLKSIZE. It is completely
OK to always let the nfs code set st_blksize to what it believes is best.
If newlib is compiled without defining HAVE_BLKSIZE then that hint
is simply ignored [but might still be honoured by application code].
> 2) A new function be added:
>   nfsInitWithBufferSize(int smallPoolDepth, int bigPoolDepth, int 
> bufferSize);
If anything, I would prefer to make this a *mount* option. This would 
(a) make
more sense [per 'connection' rather than global setting]
and (b) it would be possible to extend the existing API [by e.g., having
options appended to the server string] w/o breaking existing code or APIs.

For now, however, I believe a simple global variable should be enough. 
The new
behavior cannot do any harm (as far as I can see). If anyone want the 
old behavior
then they can change the global parameter - we can make the default/init 
setting
an option in the Makefile.

With regard to the 'pool size' -- let me clarify [and reiterate what the 
comment
in the code says]: 'small' and 'big' refer to the *send* buffer size, so 
this is only
needed for write and symlink requests. reads don't send much data ;-). 
So IMO,
the existing code was correct.

If there are no further objections then I'd go ahead and make the respective
changes using the patches where appropriate.

-- Till
>
> The existing nfsInit would call this with the existing size, so all 
> old code would continue to work.  Code that wants to specify a buffer 
> size would use the new function.
>
> On Sep 15, 2006, at 7:11 PM, Steven Johnson wrote:
>
>> Hi
>>
>>> Sound's fine.  Changing it there is quite easy.  I think it should
>>> default to 8K, and let the user tune it down by way of a sysctl.  Ill
>>> have the code added and tested, if it turns out OK, (which i suspect it
>>> will) I will post the patch.
>>>
>>>
>> As promised, see attached patches. 1 for nfs.h, and 2 for nfs.c
>>
>> The nfs.h patch and 1 of the nfs.c patches
>> (nfs_settable_buffer_size.patch) are for the  HAVE_BLKSIZE define.
>>
>> The way we approached it is that if HAVE_BLKSIZE is defined, then an
>> extra parameter must be passed to nfs_init, specifying the size of the
>> block to use. If 0 is passed for this, it defaults to the best block
>> size (which seems to be 8K for us).  Any other value up to 8K sets the
>> block size to this (over 8K sets it to 8K).  Then the code changes in
>> nfs.c are also controller by the same #def.  The reason we did it this
>> way, is so that if this define is not used, the existing behaviour will
>> prevail.  If this is defined, then the new behaviour kicks in and the
>> block size must be specified when nfs is initialised.  We couldn't see
>> any value in it being able to be changed on the fly after
>> initialisation.  For debug purposes, it is a stored as a static
>> variable, and so could be changed by a debugger to test different block
>> sizes very easily.
>>
>> The second patch to nfs.c is in regard to the big pool which was only
>> being used  on a symlink and a write, it is equally useful for a read so
>> this patch allows  the pool to be big pool on a read, instead of small
>> pool as it does now.  I don't know if this makes things better, but it
>> certainly doesn't hurt (us anyway).
>>
>> Steven Johnson
>>
>> --- librtemsNfs.h    2006-06-10 04:44:03.000000000 +1000
>> +++ /tmp/librtemsNfs.h    2006-09-15 08:43:34.309866851 +1000
>> @@ -110,7 +110,11 @@
>>   *             driver chose reasonable defaults.
>>   */
>>  int
>> +#ifdef HAVE_BLKSIZE
>> +nfsInit(int smallPoolDepth, int bigPoolDepth, int bufferSize);
>> +#else
>>  nfsInit(int smallPoolDepth, int bigPoolDepth);
>> +#endif
>>
>>  /* Driver cleanup code
>>   *
>>
>> --- nfs.c    2006-06-10 04:44:03.000000000 +1000
>> +++ /tmp/nfs.c    2006-09-15 08:40:42.085342962 +1000
>> @@ -1075,6 +1075,7 @@
>>      switch (proc) {
>>          case NFSPROC_SYMLINK:
>>          case NFSPROC_WRITE:
>> +        case NFSPROC_READ:
>>                      pool = bigPool;        break;
>>          default:    pool = smallPool;    break;
>>      }
>>
>> --- nfs.c    2006-06-10 04:44:03.000000000 +1000
>> +++ /tmp/nfs.c    2006-09-15 09:11:13.327813709 +1000
>> @@ -182,6 +182,16 @@
>>  #define UNLOCK(s)    do { rtems_semaphore_release((s)); \
>>                      } while (0)
>>
>> +/*
>> +This nfs client gets its read buffer size from the fattr data from the
>> +NFS server it connects to. If HAVE_BLKSIZE is set then this is
>> +overridden and nfsInit takes a third parameter to set the buffer size.
>> +That parameter is stored in NFS_BUFFER_SIZE
>> +*/                   
>> +#ifdef HAVE_BLKSIZE
>> +static int NFS_BUFFER_SIZE;
>> +#endif
>> +                   
>>  /*****************************************
>>      Types with Associated XDR Routines
>>   *****************************************/
>> @@ -930,7 +940,11 @@
>>   *             on the fly).
>>   */
>>  void
>> +#ifdef HAVE_BLKSIZE
>> +nfsInit(int smallPoolDepth, int bigPoolDepth, int bufferSize)
>> +#else
>>  nfsInit(int smallPoolDepth, int bigPoolDepth)
>> +#endif
>>  {
>>  entry    dummy;
>>
>> @@ -938,7 +952,14 @@
>>      fprintf(stderr,"($Id: nfs.c,v 1.2 2006/06/09 18:44:03 ericn Exp 
>> $)\n\n");
>>      fprintf(stderr,"Till Straumann, Stanford/SLAC/SSRL 2002\n");
>>      fprintf(stderr,"See LICENSE file for licensing info\n");
>> -
>> +   
>> +#ifdef HAVE_BLKSIZE
>> +    if ((bufferSize > 0) && (bufferSize < NFS_MAXDATA)) {
>> +        NFS_BUFFER_SIZE = bufferSize;
>> +    } else {
>> +        NFS_BUFFER_SIZE = NFS_MAXDATA;
>> +    }
>> +#endif
>>      /* Get a major number */
>>
>>      if (RTEMS_SUCCESSFUL != rtems_io_register_driver(0, &drvNfs, 
>> &nfsGlob.nfs_major)) {
>> @@ -2834,7 +2855,11 @@
>>      buf->st_uid        = fa->uid;
>>      buf->st_gid        = fa->gid;
>>      buf->st_size    = fa->size;
>> +#ifdef HAVE_BLKSIZE
>> +    buf->st_blksize = NFS_BUFFER_SIZE;
>> +#else   
>>      /* TODO: set to "preferred size" of this NFS client 
>> implementation */
>>      buf->st_blksize    = fa->blocksize;
>> +#endif
>>      buf->st_rdev    = fa->rdev;
>>      buf->st_blocks    = fa->blocks;
>>
>
> --Eric Norum <norume at aps.anl.gov>
> Advanced Photon Source
> Argonne National Laboratory
> (630) 252-4793
>
>




More information about the users mailing list