I confess that using read/write with textual commands seems awkward and inefficient -- I'd have thought a simple ioctl interface would have been better. It seems like mmap() has facilities that could handle this arbitration elegantly; or is the problem to provide an interface without updating any X server code? (Is this particular interface already in use on Linux?)
- Garrett On Tue, 2010-07-20 at 21:37 -0700, Alan Coopersmith wrote: > I am sponsoring this case for Henry Zhao of the x86 Platform group. > The timeout is set for Wednesday, July 28, 2010. > > Since this only adds new interfaces a release binding of Patch is > requested, though no patch release is planned at this time. > > -Alan Coopersmith- alan.coopersm...@oracle.com > Oracle Solaris Platform Engineering: X Window System > > > Template Version: @(#)sac_nextcase 1.70 03/30/10 SMI > This information is Copyright (c) 2010, Oracle and/or its affiliates. All > rights reserved. > 1. Introduction > 1.1. Project/Component Working Name: > VGA arbitration kernel driver > 1.2. Name of Document Author/Supplier: > Author: Henry Zhao > 1.3 Date of This Document: > 20 July, 2010 > 4. Technical Description > 4.1. Summary > > X server/driver's access to a VGA device falls into two categories: > legacy accesses and non-legacy accesses. Legacy accesses are accesses > whose addresses are hardcoded and shared with different VGA devices, > such as framebuffer (legacy MEM access) and VGA ports (legacy IO > access). Non-legacy accesses are accesses whose address are distinct in > the address space of different VGA devices, such as memory mapping. In a > system with multiple server instances running, there is a risk that a > legacy access may apply to all VGA devices so that a VGA device may > decode data that was not intended for it. To solve this problem, a > kernel driver is needed that controls and arbiters all the accesses such > that during a legacy access, only the intended device decodes. > > The kernel driver receives MEM/IO access requests from X server/driver, > and resolves these requests using lock/unlock mechanism to ensure that > during a legacy access, MEM/IO access is enabled (for decoding) only on > the intended device. Enabling/disabling MEM/IO access of a VGA device is > done by enabling/disabling MEM/IO bits of its PCI config space, along > with the VGA forwarding bit on any bridges on the path to the device. > > A program needs to acquire a lock on the target VGA device before it can > access it, and releases the lock after access completion. To improve > performance, two different locks, legacy locks and non-legacy locks, are > arranged in the new design. A request for a non-legacy lock is blocked > only when some other device already has a legacy lock (on the same > resources). A request for a legacy lock is blocked when some other > device already has a legacy or non-legacy lock (on the same resource). > This means a request for non-legacy lock should not be blocked just > because some other device already has a non-legacy lock (on the same > resources). Since the accesses of most graphics operations after > initialization are non-legacy, this reduces chances of locking hence > improves performance. > > Potential deadlock may occur when a program holds a non-legacy lock > while requesting a legacy lock. The problem is prevented by releasing > non-legacy lock resources the same program has acquired before going to > sleep, and restoring them after wakeup when the requesting legacy lock > is acquired. > > 4.2. Interfaces > > Both userland and kernel interfaces are provided. > > The userland interfaces include open, close, read and write system > calls. read() returns the status of the target device. write() > commands are further divided into operations to set target device, > lock/trylock target device, unlock target device, and set decoding > attributes to target device. > > Kernel interfaces, in addition to acquiring/releasing lock and setting > decoding attributes, also allow a client to register callback functions > to a VGA to device. The callback functions include resetting decoding > attributes when there is a change in configuration, and/or doing IRQ > related processing when a device's MEM/IO enable/disable status > changes. The latter is needed because when MEM access is disabled, > any interrupts, if generated, would not be processed. > > Exported Interfaces > ------------------- > > Interface Classification Comment > > /devices/vga_arbiter:vga_arbiter > Uncommitted device > /platform/kernel/drv/<amd64>/vga_arbiter > Uncommitted driver > /platform/kernel/drv/vga_arbiter.conf > Uncommitted config file > > Userland > -------- > > Use the standard open, close, read, write system calls to access the > device, with string format of read/write commands defined as follows: > > "target <card_ID>" uncommitted write to device to set > target > "lock <io_state>" uncommitted write to device to set lock > (wait) > "trylock <io_state>" uncommitted write to device to set lock (no > wait) > "unlock <io_state>" uncommitted write to device to > unlock > "unlock all" uncommitted write to device to unlock > "decodes <io_state>" uncommitted write to device to set decoding > attr > > "count:<num>,card_ID,decodes=<io_state>,owns=<io_state>,legalocks=<io_state>(lic:lmc),normlocks=<io_state>(nic:nmc)" > uncommitted read from device > > <card_ID> is in a format of "PCI:domain:bus:dev.fn" > <io_state> is a string "io+mem+IO+MEM" or a part of it > > Kernel > ------ > > void vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes) > uncommitted set decoding attributes > > int vga_get(struct pci_dev *pdev, unsigned int rsrc, > unsigned int io_norm_cnt, unsigned int mem_norm_cnt, > int interruptible); > uncommitted acquire a lock (wait) > > int vga_tryget(struct pci_dev *pdev, unsigned int rsrc) > uncommitted acquire a lock (no wait) > > void vga_put(struct pci_dev *pdev, unsigned int rsrc) > uncommitted release a lock > > int vga_client_register(struct pci_dev *pdev, void *cookie, > void (*irq_set_state)(void *cookie, bool state), > unsigned int (*set_vga_decode)(void *cookie, bool state)) > uncommitted register callback functions > > 4.3. Implementation > > * The original code (using one lock) resides in linux kernel tree: > > drivers/gpr/vga/vgaarb.c > drivers/include/linux/vgaarb.h > > * Code is modified to add an additional lock (non legacy lock) to > improve performance when ported to Solaris. > > * Hot-plugging (to dynamically handle adding/removing vga devices) will > be implemented in second phase. > > > > 6. Resources and Schedule > 6.4. Steering Committee requested information > 6.4.1. Consolidation C-team Name: > ON > 6.5. ARC review type: FastTrack > 6.6. ARC Exposure: open > > _______________________________________________ > opensolaris-arc mailing list > opensolaris-arc@opensolaris.org _______________________________________________ opensolaris-arc mailing list opensolaris-arc@opensolaris.org