• Matan Barak's avatar
    IB/core: Add new ioctl interface · fac9658c
    Matan Barak authored
    In this ioctl interface, processing the command starts from
    properties of the command and fetching the appropriate user objects
    before calling the handler.
    
    Parsing and validation is done according to a specifier declared by
    the driver's code. In the driver, all supported objects are declared.
    These objects are separated to different object namepsaces. Dividing
    objects to namespaces is done at initialization by using the higher
    bits of the object ids. This initialization can mix objects declared
    in different places to one parsing tree using in this ioctl interface.
    
    For each object we list all supported methods. Similarly to objects,
    methods are separated to method namespaces too. Namespacing is done
    similarly to the objects case. This could be used in order to add
    methods to an existing object.
    
    Each method has a specific handler, which could be either a default
    handler or a driver specific handler.
    Along with the handler, a bunch of attributes are specified as well.
    Similarly to objects and method, attributes are namespaced and hashed
    by their ids at initialization too. All supported attributes are
    subject to automatic fetching and validation. These attributes include
    the command, response and the method's related objects' ids.
    
    When these entities (objects, methods and attributes) are used, the
    high bits of the entities ids are used in order to calculate the hash
    bucket index. Then, these high bits are masked out in order to have a
    zero based index. Since we use these high bits for both bucketing and
    namespacing, we get a compact representation and O(1) array access.
    This is mandatory for efficient dispatching.
    
    Each attribute has a type (PTR_IN, PTR_OUT, IDR and FD) and a length.
    Attributes could be validated through some attributes, like:
    (*) Minimum size / Exact size
    (*) Fops for FD
    (*) Object type for IDR
    
    If an IDR/fd attribute is specified, the kernel also states the object
    type and the required access (NEW, WRITE, READ or DESTROY).
    All uobject/fd management is done automatically by the infrastructure,
    meaning - the infrastructure will fail concurrent commands that at
    least one of them requires concurrent access (WRITE/DESTROY),
    synchronize actions with device removals (dissociate context events)
    and take care of reference counting (increase/decrease) for concurrent
    actions invocation. The reference counts on the actual kernel objects
    shall be handled by the handlers.
    
     objects
    +--------+
    |        |
    |        |   methods                                                                +--------+
    |        |   ns         method      method_spec                           +-----+   |len     |
    +--------+  +------+[d]+-------+   +----------------+[d]+------------+    |attr1+-> |type    |
    | object +> |method+-> | spec  +-> +  attr_buckets  +-> |default_chain+--> +-----+   |idr_type|
    +--------+  +------+   |handler|   |                |   +------------+    |attr2|   |access  |
    |        |  |      |   +-------+   +----------------+   |driver chain|    +-----+   +--------+
    |        |  |      |                                    +------------+
    |        |  +------+
    |        |
    |        |
    |        |
    |        |
    |        |
    |        |
    |        |
    |        |
    |        |
    |        |
    +--------+
    
    [d] = Hash ids to groups using the high order bits
    
    The right types table is also chosen by using the high bits from
    the ids. Currently we have either default or driver specific groups.
    
    Once validation and object fetching (or creation) completed, we call
    the handler:
    int (*handler)(struct ib_device *ib_dev, struct ib_uverbs_file *ufile,
                   struct uverbs_attr_bundle *ctx);
    
    ctx bundles attributes of different namespaces. Each element there
    is an array of attributes which corresponds to one namespaces of
    attributes. For example, in the usually used case:
    
     ctx                               core
    +----------------------------+     +------------+
    | core:                      +---> | valid      |
    +----------------------------+     | cmd_attr   |
    | driver:                    |     +------------+
    |----------------------------+--+  | valid      |
                                    |  | cmd_attr   |
                                    |  +------------+
                                    |  | valid      |
                                    |  | obj_attr   |
                                    |  +------------+
                                    |
                                    |  drivers
                                    |  +------------+
                                    +> | valid      |
                                       | cmd_attr   |
                                       +------------+
                                       | valid      |
                                       | cmd_attr   |
                                       +------------+
                                       | valid      |
                                       | obj_attr   |
                                       +------------+
    Signed-off-by: default avatarMatan Barak <matanb@mellanox.com>
    Reviewed-by: default avatarYishai Hadas <yishaih@mellanox.com>
    Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
    fac9658c
ib_verbs.h 108 KB