| INFINIBAND MIDLAYER LOCKING | |
| This guide is an attempt to make explicit the locking assumptions | |
| made by the InfiniBand midlayer. It describes the requirements on | |
| both low-level drivers that sit below the midlayer and upper level | |
| protocols that use the midlayer. | |
| Sleeping and interrupt context | |
| With the following exceptions, a low-level driver implementation of | |
| all of the methods in struct ib_device may sleep. The exceptions | |
| are any methods from the list: | |
| create_ah | |
| modify_ah | |
| query_ah | |
| destroy_ah | |
| bind_mw | |
| post_send | |
| post_recv | |
| poll_cq | |
| req_notify_cq | |
| map_phys_fmr | |
| which may not sleep and must be callable from any context. | |
| The corresponding functions exported to upper level protocol | |
| consumers: | |
| ib_create_ah | |
| ib_modify_ah | |
| ib_query_ah | |
| ib_destroy_ah | |
| ib_bind_mw | |
| ib_post_send | |
| ib_post_recv | |
| ib_req_notify_cq | |
| ib_map_phys_fmr | |
| are therefore safe to call from any context. | |
| In addition, the function | |
| ib_dispatch_event | |
| used by low-level drivers to dispatch asynchronous events through | |
| the midlayer is also safe to call from any context. | |
| Reentrancy | |
| All of the methods in struct ib_device exported by a low-level | |
| driver must be fully reentrant. The low-level driver is required to | |
| perform all synchronization necessary to maintain consistency, even | |
| if multiple function calls using the same object are run | |
| simultaneously. | |
| The IB midlayer does not perform any serialization of function calls. | |
| Because low-level drivers are reentrant, upper level protocol | |
| consumers are not required to perform any serialization. However, | |
| some serialization may be required to get sensible results. For | |
| example, a consumer may safely call ib_poll_cq() on multiple CPUs | |
| simultaneously. However, the ordering of the work completion | |
| information between different calls of ib_poll_cq() is not defined. | |
| Callbacks | |
| A low-level driver must not perform a callback directly from the | |
| same callchain as an ib_device method call. For example, it is not | |
| allowed for a low-level driver to call a consumer's completion event | |
| handler directly from its post_send method. Instead, the low-level | |
| driver should defer this callback by, for example, scheduling a | |
| tasklet to perform the callback. | |
| The low-level driver is responsible for ensuring that multiple | |
| completion event handlers for the same CQ are not called | |
| simultaneously. The driver must guarantee that only one CQ event | |
| handler for a given CQ is running at a time. In other words, the | |
| following situation is not allowed: | |
| CPU1 CPU2 | |
| low-level driver -> | |
| consumer CQ event callback: | |
| /* ... */ | |
| ib_req_notify_cq(cq, ...); | |
| low-level driver -> | |
| /* ... */ consumer CQ event callback: | |
| /* ... */ | |
| return from CQ event handler | |
| The context in which completion event and asynchronous event | |
| callbacks run is not defined. Depending on the low-level driver, it | |
| may be process context, softirq context, or interrupt context. | |
| Upper level protocol consumers may not sleep in a callback. | |
| Hot-plug | |
| A low-level driver announces that a device is ready for use by | |
| consumers when it calls ib_register_device(), all initialization | |
| must be complete before this call. The device must remain usable | |
| until the driver's call to ib_unregister_device() has returned. | |
| A low-level driver must call ib_register_device() and | |
| ib_unregister_device() from process context. It must not hold any | |
| semaphores that could cause deadlock if a consumer calls back into | |
| the driver across these calls. | |
| An upper level protocol consumer may begin using an IB device as | |
| soon as the add method of its struct ib_client is called for that | |
| device. A consumer must finish all cleanup and free all resources | |
| relating to a device before returning from the remove method. | |
| A consumer is permitted to sleep in its add and remove methods. |