Extremely slooooow __sys_ftruncate?

David Schultz das at FreeBSD.ORG
Fri Mar 21 13:03:41 PDT 2008


On Thu, Mar 20, 2008, Jeff Roberson wrote:
> On Thu, 20 Mar 2008, Steve Kargl wrote:
> 
> >On Thu, Mar 20, 2008 at 08:02:54PM -0700, Steve Kargl wrote:
> >>In the process of helping to debug a problem with gcc-4.4.0
> >>(actually a gfortran problem), I run gprof on the executable.
> >>The profile shows that __sys_ftruncate is extremely slow.
> >>
> >>  %   cumulative   self              self     total
> >> time   seconds   seconds    calls  ms/call  ms/call  name
> >> 85.6       6.05     6.05    51830     0.12     0.12  __sys_ftruncate [2]
> >>  5.6       6.44     0.40        0  100.00%           .mcount (101)
> >>  1.7       6.56     0.12    51872     0.00     0.00  _lseek [5]
> >>  1.6       6.67     0.11    52055     0.00     0.00  sigprocmask [6]
> >>  0.8       6.73     0.06   103687     0.00     0.00  memset [14]
> >>  0.4       6.76     0.03      488     0.06     0.06  __sys_write [18]
> >>  0.4       6.79     0.03        0  100.00%           
> >>  formatted_transfer_scalar
> >>
> >>time ./z
> >>     184.21 real         0.98 user         6.57 sys
> >>
> >>This program should finish well under 184 seconds.  The same program
> >>and exact same gcc/gfortran source on linux shows
> >> real    0m0.555s    user    0m0.103s    sys     0m0.452s
> >>
> >>Is __sys_ftruncate known to have performance problems?
> >>
> >
> >Well, I tried to kludge together a C example based on the
> >the Fortran test code and gfortran runtime library.
> 
> Thanks for the test code.  truncate is only handled by softupdates when 
> it's a truncate to 0.  Otherwise it's synchronous. :/

There was a bug that was fixed several years ago in which
repeatedly writing to a file and then truncating it could cause
thousands of update dependencies on indirect blocks to accumulate,
leading to an immediate panic. The fix was to fsync the file every
50 truncates, which means that truncate(2) can get "charged" for a
lot of deferred softupdates work.

By the way, the tunable debug.maxindirdeps determines the number
of truncates that can occur before the fsync happens.


More information about the freebsd-current mailing list