Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

RDMA: Provide documentation about the uABI compatibility rules

Write down how all of this is supposed to work using the new helpers.

Link: https://patch.msgid.link/r/7-v3-bd56dd443069+49-bnxt_re_uapi_jgg@nvidia.com
Tested-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Acked-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

+87
+87
include/rdma/ib_verbs.h
··· 1577 1577 const struct uverbs_api_object *uapi_object; 1578 1578 }; 1579 1579 1580 + /** 1581 + * struct ib_udata - Driver request/response data from userspace 1582 + * @inbuf: Pointer to request data from userspace 1583 + * @outbuf: Pointer to response buffer in userspace 1584 + * @inlen: Length of request data 1585 + * @outlen: Length of response buffer 1586 + * 1587 + * struct ib_udata is used to hold the driver data request and response 1588 + * structures defined in the uapi. They follow these rules for forwards and 1589 + * backwards compatibility: 1590 + * 1591 + * 1) Userspace can provide a longer request so long as the trailing part the 1592 + * kernel doesn't understand is all zeros. 1593 + * 1594 + * This provides a degree of safety if userspace wrongly tries to use a new 1595 + * feature the kernel does not understand with some non-zero value. 1596 + * 1597 + * It allows a simpler rdma-core implementation because the library can 1598 + * simply always use the latest structs for the request, even if they are 1599 + * bigger. It simply has to avoid using the new members if they are not 1600 + * supported/required. 1601 + * 1602 + * 2) Userspace can provide a shorter request; the kernel will zero-pad it out 1603 + * to fill the storage. The newer kernel should understand that older 1604 + * userspace will provide 0 to new fields. The kernel has three options to 1605 + * enable new request fields: 1606 + * 1607 + * - Input comp_mask that says the field is supported 1608 + * - Look for non-zero values 1609 + * - Check if the udata->inlen size covers the field 1610 + * 1611 + * This also corrects any bugs related to not filling in request structures 1612 + * as the new helper always fully writes to the struct. 1613 + * 1614 + * 3) Userspace can provide a shorter or longer response struct. If shorter, 1615 + * the kernel reply is truncated. The kernel should be designed to not write 1616 + * to new reply fields unless userspace has affirmatively requested them. 1617 + * 1618 + * If the user buffer is longer, the kernel will zero-fill it. 1619 + * 1620 + * Userspace has three options to enable new response fields: 1621 + * 1622 + * - Output comp_mask that says the field is supported 1623 + * - Look for non-zero values 1624 + * - Infer the output must be valid because the request contents demand it 1625 + * and old kernels will fail the request 1626 + * 1627 + * The following helper functions implement these semantics: 1628 + * 1629 + * ib_copy_validate_udata_in() - Checks the minimum length, and zero trailing:: 1630 + * 1631 + * struct driver_create_cq_req req; 1632 + * int err; 1633 + * 1634 + * err = ib_copy_validate_udata_in(udata, req, end_member); 1635 + * if (err) 1636 + * return err; 1637 + * 1638 + * The third argument specifies the last member of the struct in the first 1639 + * kernel version that introduced it, establishing the minimum required size. 1640 + * 1641 + * ib_copy_validate_udata_in_cm() - The above but also validate a 1642 + * comp_mask member only has supported bits set:: 1643 + * 1644 + * err = ib_copy_validate_udata_in_cm(udata, req, first_version_last_member, 1645 + * DRIVER_CREATE_CQ_MASK_FEATURE_A | 1646 + * DRIVER_CREATE_CQ_MASK_FEATURE_B); 1647 + * 1648 + * ib_respond_udata() - Implements the response rules:: 1649 + * 1650 + * struct driver_create_cq_resp resp = {}; 1651 + * 1652 + * resp.some_field = value; 1653 + * return ib_respond_udata(udata, resp); 1654 + * 1655 + * ib_is_udata_in_empty() - Used instead of ib_copy_validate_udata_in() if the 1656 + * driver does not have a request structure:: 1657 + * 1658 + * ret = ib_is_udata_in_empty(udata); 1659 + * if (ret) 1660 + * return ret; 1661 + * 1662 + * Similarly ib_respond_empty_udata() is used instead of ib_respond_udata() if 1663 + * the driver does not have a response structure:: 1664 + * 1665 + * return ib_respond_empty_udata(udata); 1666 + */ 1580 1667 struct ib_udata { 1581 1668 const void __user *inbuf; 1582 1669 void __user *outbuf;