home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / unix / bsd / 4485 < prev    next >
Encoding:
Internet Message Format  |  1992-08-20  |  7.3 KB

  1. Xref: sparky comp.unix.bsd:4485 comp.bugs.4bsd:205
  2. Newsgroups: comp.unix.bsd,comp.bugs.4bsd
  3. Path: sparky!uunet!iWarp.intel.com|ichips!intelhf!agora!davidg
  4. From: davidg@agora.rain.com (David Greenman)
  5. Subject: 386BSD kernel bugs w/fixes
  6. Message-ID: <1992Aug20.105712.26856@agora.uucp>
  7. Sender: davidg@agora.uucp (David Greenman)
  8. Organization: Open Communications Forum
  9. Date: Thu, 20 Aug 1992 10:57:12 GMT
  10. Lines: 176
  11.  
  12.  
  13.    This patch-kit contains a number of bugfixes for 386BSD.
  14.  
  15. 1) The filesystem buffer cache has a major problem with the proper
  16.     queueing of buffers to the correct queue. Specifically, in the
  17.     files /sys/ufs/ufs_vnops.c and /sys/kern/spec_vnops.c the flag
  18.     B_AGE is incorrectly getting set in bp->b_flags when a read
  19.     finishes. This causes almost all buffers to be released to the
  20.     AGE queue where they are then immediately reused for the next
  21.     read - resulting in worst case cache performance. My under-
  22.     standing of the original intent in the setting of B_AGE (in the
  23.     case of a buffered read - a different intent in a write) was to
  24.     cause the quick re-use of buffers that are fragments of a complete
  25.     filesystem block with the assumption that the same request for
  26.     a fragment wasn't likely. The assumption and the algorithm that
  27.     determines a 'fragment' are bogus. The fix is to simply not set
  28.     the flag in the case of a read. This substantially improves file-
  29.     system performance in 386BSD.
  30. 2) The FS buffer cache has a bug in the hash index calculation. In the
  31.     file /sys/sys/buf.h the index for bufhash[] that is used in the
  32.     #define BUFHASH almost always yields a zero index. This completely
  33.     defeats the purpose/advantages of the buffer hash table. The
  34.     problem developed during the conversion to a vnode based (rather
  35.     than device based) buffer cache. The fix is to change the equa-
  36.     tion to one that provides a fairly even distribution in the
  37.     hash table. My fix for this substantially improves the perform-
  38.     ance of the incore() routine which finds in-cache buffers.
  39. 3) The FS buffer cache has another bug that causes memory for buffers to
  40.     be allocated twice. The bug is in the file /sys/kern/vfs__bio.c,
  41.     in the function getnewbuf(). The problem is that bp->bufsize is
  42.     not initialized when a new buffer is used for the first time.
  43.     Fortunately, allocbuf() frees the previously malloc'd space so no
  44.     memory is lost. However, the variable freebufspace is left incor-
  45.     rectly reduced. The fix for this is to fill in bp->bufsize just
  46.     after mallocing the memory in getnewbuf().
  47. 4) The virtual memory system has a bug that will prevent a process from
  48.     growing in its virtual size greater than 6MB data/stack. This is
  49.     caused by the incorrect process limit being checked in /sys/vm/
  50.     vm_unix.c. As they are defined in /sys/i386/include/vmparam.h,
  51.     the constants DFLDSIZ and DFLSSIZ specify the initial limit (the
  52.     limit when the process is created in execve()) for a process. The
  53.     constants MAXTSIZ and MAXSSIZ specify the maximum that a process
  54.     can grow. These constants are copied into process zero's proc->
  55.     p_limit[] and are used as a prototype for all processes. rlim_cur
  56.     contains DFLDSIZ/DFLSSIZ, and rlim_max contains MAXDSIZ/MAXSSIZ.
  57.     rlim_max should therefore be used to limit the process's virtual
  58.     size growth. However, the check is against rlim_cur. The fix is
  59.     to change the check to rlim_max. One might also note that 6MB for
  60.     DFLDSIZ/DFLSSIZ in vmparam.h is very low and should be increased
  61.     to something more reasonable. Most vendors specify an initial
  62.     limit of 32MB.
  63. 5) The virtual memory system in 386BSD 0.1 has not yet been completed.
  64.     The system has a stub routine for swapout() which does nothing
  65.     but unset SLOAD and remove the process from the run queue. It
  66.     does not pageout or swapout a single page. The calling of it
  67.     with this behavior causes unnecessary scheduling overhead, and 
  68.     also causes the 'ps' command to omit some process information. The
  69.     temporary fix is to comment out the call to swap_threads() in
  70.     /sys/vm/vm_pageout.c. Of course this fix should be removed when
  71.     the VM code has been completed. (Actually, with a good paging
  72.     algorithm, swapping shouldn't be necessary...but then there's
  73.     tradition... I'm working on writing some better paging code for
  74.     386BSD.)
  75.  
  76.  
  77. ---
  78. David Greenman
  79. davidg%implode@percy.rain.com
  80.  
  81. Here are the patches:
  82.  
  83.  
  84. *** /sys/ufs/ufs_vnops.c.01orig    Thu Aug 13 23:11:01 1992
  85. --- /sys/ufs/ufs_vnops.c    Sun Aug 16 02:49:02 1992
  86. ***************
  87. *** 497,504 ****
  88. --- 497,506 ----
  89.               return (error);
  90.           }
  91.           error = uiomove(bp->b_un.b_addr + on, (int)n, uio);
  92. + #if 0
  93.           if (n + on == fs->fs_bsize || uio->uio_offset == ip->i_size)
  94.               bp->b_flags |= B_AGE;
  95. + #endif
  96.           brelse(bp);
  97.       } while (error == 0 && uio->uio_resid > 0 && n != 0);
  98.       return (error);
  99. *** /sys/kern/spec_vnops.c.01orig    Sun Jun  7 16:42:13 1992
  100. --- /sys/kern/spec_vnops.c    Sun Aug 16 02:54:32 1992
  101. ***************
  102. *** 218,225 ****
  103. --- 218,227 ----
  104.                   return (error);
  105.               }
  106.               error = uiomove(bp->b_un.b_addr + on, n, uio);
  107. + #if 0
  108.               if (n + on == bsize)
  109.                   bp->b_flags |= B_AGE;
  110. + #endif
  111.               brelse(bp);
  112.           } while (error == 0 && uio->uio_resid > 0 && n != 0);
  113.           return (error);
  114. *** /sys/sys/buf.h.01orig    Sat Jun 20 20:02:53 1992
  115. --- /sys/sys/buf.h    Sun Aug 16 03:34:06 1992
  116. ***************
  117. *** 112,121 ****
  118.   #define RND    (MAXBSIZE/DEV_BSIZE)
  119.   #if    ((BUFHSZ&(BUFHSZ-1)) == 0)
  120.   #define    BUFHASH(dvp, dblkno)    \
  121. !     ((struct buf *)&bufhash[((int)(dvp)+(((int)(dblkno))/RND))&(BUFHSZ-1)])
  122.   #else
  123.   #define    BUFHASH(dvp, dblkno)    \
  124. !     ((struct buf *)&bufhash[((int)(dvp)+(((int)(dblkno))/RND)) % BUFHSZ])
  125.   #endif
  126.   
  127.   struct    buf *buf;        /* the buffer pool itself */
  128. --- 112,121 ----
  129.   #define RND    (MAXBSIZE/DEV_BSIZE)
  130.   #if    ((BUFHSZ&(BUFHSZ-1)) == 0)
  131.   #define    BUFHASH(dvp, dblkno)    \
  132. !     ((struct buf *)&bufhash[((int)(dvp)/sizeof(struct vnode)+(int)(dblkno))&(BUFHSZ-1)])
  133.   #else
  134.   #define    BUFHASH(dvp, dblkno)    \
  135. !     ((struct buf *)&bufhash[((int)(dvp)/sizeof(struct vnode)+(int)(dblkno)) % BUFHSZ])
  136.   #endif
  137.   
  138.   struct    buf *buf;        /* the buffer pool itself */
  139. *** /sys/kern/vfs__bio.c.01orig    Sun Jun 28 20:49:18 1992
  140. --- /sys/kern/vfs__bio.c    Mon Aug 17 02:40:09 1992
  141. ***************
  142. *** 344,349 ****
  143. --- 344,350 ----
  144.           bp->b_flags = B_BUSY | B_INVAL;
  145.           bremfree(bp);
  146.           bp->b_un.b_addr = addr;
  147. +         bp->b_bufsize = sz;
  148.           goto fillin;
  149.       }
  150.   
  151. *** /sys/vm/vm_unix.c.01orig    Sun Jul  5 11:53:46 1992
  152. --- /sys/vm/vm_unix.c    Mon Aug 17 04:53:40 1992
  153. ***************
  154. *** 65,71 ****
  155.   
  156.       old = (vm_offset_t)vm->vm_daddr;
  157.       new = round_page(uap->nsiz);
  158. !     if ((int)(new - old) > p->p_rlimit[RLIMIT_DATA].rlim_cur)
  159.           return(ENOMEM);
  160.       old = round_page(old + ctob(vm->vm_dsize));
  161.       diff = new - old;
  162. --- 65,71 ----
  163.   
  164.       old = (vm_offset_t)vm->vm_daddr;
  165.       new = round_page(uap->nsiz);
  166. !     if ((int)(new - old) > p->p_rlimit[RLIMIT_DATA].rlim_max)
  167.           return(ENOMEM);
  168.       old = round_page(old + ctob(vm->vm_dsize));
  169.       diff = new - old;
  170. ***************
  171. *** 113,119 ****
  172.        * Really need to check vs limit and increment stack size if ok.
  173.        */
  174.       si = clrnd(btoc(vm->vm_maxsaddr + MAXSSIZ - sp) - vm->vm_ssize);
  175. !     if (vm->vm_ssize + si > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur))
  176.           return (0);
  177.       vm->vm_ssize += si;
  178.       return (1);
  179. --- 113,119 ----
  180.        * Really need to check vs limit and increment stack size if ok.
  181.        */
  182.       si = clrnd(btoc(vm->vm_maxsaddr + MAXSSIZ - sp) - vm->vm_ssize);
  183. !     if (vm->vm_ssize + si > btoc(p->p_rlimit[RLIMIT_STACK].rlim_max))
  184.           return (0);
  185.       vm->vm_ssize += si;
  186.       return (1);
  187.     
  188.