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

Reply via email to