Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Dec 1998 14:47:31 -0500 (EST)
From:      "Mark J. Taylor" <mtaylor@cybernet.com>
To:        freebsd-hackers@FreeBSD.ORG
Subject:   dpt_control.c problems, with patchs
Message-ID:  <XFMail.981228144731.mtaylor@cybernet.com>

next in thread | raw e-mail | index | archive | help

I have a machine here which page faults when there are five drives present.
With only four, it is not a problem.  The following is an explaination and
fix:



There is a page-boundary problem in 2.2.8's /sys/dev/dpt_scsi.c:dpt_physmap
routine.  It goes all the way back to inception, and it is in 3.0 as well.


Do the math:
  req_size = 1024
  req_paddr = 0xfeff5
yields:
  size = (1024/4096 + 1) * 4096 = 4096
  paddr = 0xfeff5 & 0xfffff000 = 0xfe000

Then, accessing 0xfeff5 + 14 (to get dpt_sysinfo.drives[1].sectors) will
generate a page fault at 0xff003, because only a page (0x1000) of bytes
are mapped.

The problem comes in chopping off (rounding) the lower three nibbles of
the requested address.  To compensate for that, I add an 'extra' page to
the requested size.

One must compensate for this compensation in the dpt_unphysmap routine
as well.



The fix:


RCS file: dpt_control.c,v
retrieving revision 1.3.2.4
diff -c5 -r1.3.2.4 dpt_control.c
*** dpt_control.c       1998/06/02 23:28:13     1.3.2.4
--- dpt_control.c       1998/12/28 18:55:32
***************
*** 122,131 ****
--- 122,132 ----
        u_int32_t       paddr;
        u_int32_t       offset;
  
  
  
+       req_size += PAGE_SIZE;
        size = (req_size / PAGE_SIZE + 1) * PAGE_SIZE;
        paddr = req_paddr & 0xfffff000;
        offset = req_paddr - paddr;
  
        va = kmem_alloc_pageable(kernel_map, size);
***************
*** 151,160 ****
--- 152,162 ----
  static void
  dpt_unphysmap(u_int8_t * vaddr, vm_size_t size)
  {
        int             ndx;
  
+       size += PAGE_SIZE;
        for (ndx = 0; ndx < size; ndx += PAGE_SIZE) {
                pmap_kremove((vm_offset_t) vaddr + ndx);
        }
  
        kmem_free(kernel_map, (vm_offset_t) vaddr, size);





There is alse a small problem in the dpt_control.c:dpt_get_sysinfo
routine where a splx() is needed upon an error exit of the routine.
The correction of this is left as an exercise to the reader.  :)


I'd appreciate it if someone with commit privs. made this patch to
the kernel.



Thanks for FreeBSD!



-Mark Taylor
NetMAX Developer
mtaylor@cybernet.com
http://www.netmax.com/



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?XFMail.981228144731.mtaylor>