Subject: kern/1289: cdev_fb_init() breaks Xserver on DEC framebuffers
To: None <gnats-bugs@gnats.netbsd.org>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: netbsd-bugs
Date: 07/27/1995 14:56:17
>Number: 1289
>Category: kern
>Synopsis: cdevsw macro for frame-buffers insufficently general
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Jul 27 18:05:04 1995
>Last-Modified:
>Originator: Jonathan Stone
>Organization:
>Release: NetBSD-current as at (or near) 24 July 1995.
>Environment:
System: NetBSD Reno.Stanford.EDU 1.0A NetBSD 1.0A (CURRENT) #420: Tue Jul 25 16:50:58 PDT 1995 jonathan@Reno.Stanford.EDU:/usr/src/sys/arch/pmax/compile/CURRENT pmax
>Description:
The file /usr/src/sys/sys/conf.h has a macro, cdev_fb_init(),
which purports to initalize entries for framebuffers in a
struct cdevsw. This macro sets the ``select'' entry to
enodev. This is not adequate for DEC framebuffers (on pmax,
vax, and alpha, from QVSS onward) which use a shared-memory queue
for mouse and keyboard events. This buffer is shared by
the kernel and whatever application has the framebuffer mapped
into user-space. (The kernel updates the position of a pointer
sprite, asynchronously with whatever the application does.)
These systems use select() on a framebuffer to notify an application
(the X server) that new events have been placed in the shared-memory
queue.
Lack of a select() entry causes X servers for DEC framebuffers
to busy-wait, causing 95% to 100% system load.
The cdev_fb_init() macro (or some variant of it) should really be
general enough to support framebuffers on all NetBSD platforms.
Currently, it clearly isn't.
>How-To-Repeat:
Build a NetBSD/pmax kernel. Add entries in the cdevsw
for a framebuffer, using cdev_fb_init(). Start a NetBSD/pmax X11R5
server (available at ftp://ftp.unit.no/pub/NetBSD/arch/pmax/X11R5/)
Watch the system time (as shown by top) hit 100%.
(Don't do this, it causes awful interactive response.)
>Fix:
Change the cdev_init_fb() macro to cause a select routine,
and update its current clients to provide a null select routine.
The following works as a gross hack for the pmax.
I haven't committed it because I think that the right place for the
initializatio macro is sys/sys/conf.h, not arch/pmax/pmax/conf.h.
(It may be that two macros, one with a select entry and one without,
is a better solution; I'm agnostic on that.)
*** conf.c.DIST Tue Jul 4 23:55:14 1995
--- conf.c Mon Jul 24 10:26:05 1995
***************
*** 115,121 ****
--- 115,140 ----
cdev_decl(rcons);
#include "fb.h"
cdev_decl(fb);
+ #include "pm.h"
+ cdev_decl(pm);
+ #include "cfb.h"
+ cdev_decl(cfb);
+ #include "xcfb.h"
+ cdev_decl(xcfb);
+ #include "mfb.h"
+ cdev_decl(mfb);
+
+ /* a framebuffer with an attached mouse: */
+ /* open, close, ioctl, mmap */
+
+ #define cdev_fbm_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
+ (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
+ (dev_type_stop((*))) enodev, 0, dev_init(c,n,select), \
+ dev_init(c,n,mmap) }
+
+
struct cdevsw cdevsw[] =
{
cdev_cn_init(1,cn), /* 0: virtual console */
***************
*** 126,142 ****
cdev_ptc_init(NPTY,ptc), /* 5: pseudo-tty master */
cdev_log_init(1,log), /* 6: /dev/klog */
cdev_fd_init(1,fd), /* 7: file descriptor pseudo-dev */
! cdev_notdef(), /* 8: 2100/3100 frame buffer */
cdev_notdef(), /* 9: old slot for SCSI disk */
cdev_tape_init(NTZ,tz), /* 10: SCSI tape */
cdev_disk_init(NVND,vnd), /* 11: vnode disk driver */
cdev_bpftun_init(NBPFILTER,bpf),/* 12: Berkeley packet filter */
! cdev_notdef(), /* 13: color frame buffer */
! cdev_notdef(), /* 14: maxine color frame buffer */
cdev_tty_init(NDTOP,dtop), /* 15: desktop bus interface */
cdev_tty_init(NDC,dc), /* 16: dc7085 serial interface */
cdev_tty_init(NSCC,scc), /* 17: scc 82530 serial interface */
! cdev_notdef(), /* 18: mono frame buffer */
cdev_notdef(), /* 19: mt */
cdev_tty_init(NPTY,pts), /* 20: pty slave */
cdev_ptc_init(NPTY,ptc), /* 21: pty master */
--- 145,161 ----
cdev_ptc_init(NPTY,ptc), /* 5: pseudo-tty master */
cdev_log_init(1,log), /* 6: /dev/klog */
cdev_fd_init(1,fd), /* 7: file descriptor pseudo-dev */
! cdev_fbm_init(NPM,pm), /* 8: 2100/3100 frame buffer */
cdev_notdef(), /* 9: old slot for SCSI disk */
cdev_tape_init(NTZ,tz), /* 10: SCSI tape */
cdev_disk_init(NVND,vnd), /* 11: vnode disk driver */
cdev_bpftun_init(NBPFILTER,bpf),/* 12: Berkeley packet filter */
! cdev_fbm_init(NCFB,cfb), /* 13: color frame buffer */
! cdev_fbm_init(NXCFB,xcfb), /* 14: maxine color frame buffer */
cdev_tty_init(NDTOP,dtop), /* 15: desktop bus interface */
cdev_tty_init(NDC,dc), /* 16: dc7085 serial interface */
cdev_tty_init(NSCC,scc), /* 17: scc 82530 serial interface */
! cdev_fbm_init(NMFB,mfb), /* 18: mono frame buffer */
cdev_notdef(), /* 19: mt */
cdev_tty_init(NPTY,pts), /* 20: pty slave */
cdev_ptc_init(NPTY,ptc), /* 21: pty master */
***************
*** 206,212 ****
cdev_notdef(), /* 83: fd */
cdev_notdef(), /* 84: DTi */
cdev_tty_init(NRCONS,rcons), /* 85: raster console pseudo-device */
! cdev_fb_init(NFB,fb), /* 86: frame buffer pseudo-device */
};
int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]);
--- 225,231 ----
cdev_notdef(), /* 83: fd */
cdev_notdef(), /* 84: DTi */
cdev_tty_init(NRCONS,rcons), /* 85: raster console pseudo-device */
! cdev_fbm_init(NFB,fb), /* 86: frame buffer pseudo-device */
};
int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]);
>Audit-Trail:
>Unformatted: