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

Reply via email to