STRUCT IB_UDATA(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… struct ib_udata(9) β€” from the Kernel API Manual ✨

okay bestie, sit down, we're learning about struct ib_udata today and honestly? it's giving "the translator between userspace and your driver" and it ate. 🫢


🌸 NAME 🌸

struct ib_udata β€” the driver request/response data that comes from userspace, no cap πŸ’–


✨ SYNOPSIS ✨

struct ib_udata {
    const void __user *inbuf;
    void __user *outbuf;
    size_t inlen;
    size_t outlen;
 };

πŸŽ€ Members πŸŽ€

  • inbuf β€” pointer to the request data coming in from userspace πŸ“₯
  • outbuf β€” pointer to the response buffer living in userspace πŸ“€
  • inlen β€” length of the request data
  • outlen β€” length of the response buffer

πŸ’œ Description πŸ’œ

so struct ib_udata is literally just the container for the driver data request and response structures that are defined in the uapi. that's its whole job. and it follows these rules for forwards and backwards compatibility β€” listen up, this is the important part:

  1. userspace can hand over a longer request, as long as the trailing part that the kernel doesn't understand is entirely zeros. ✨

this gives you a degree of safety if userspace wrongly tries to use some new feature the kernel doesn't understand yet and slaps some non-zero value in there. ngl that's kinda thoughtful of them.

it also allows a simpler rdma-core implementation, because the library can just always use the latest structs for the request even if they're bigger. it simply has to avoid using the new members if they're not supported/required. lowkey iconic.

  1. userspace can hand over a shorter request β€” and the kernel will zero-pad it out to fill the storage. the newer kernel should understand that older userspace will just pass 0 for the new fields. the kernel has three options to enable new request fields:
  • an input comp_mask that says the field is supported
  • look for non-zero values
  • check if the udata->inlen size covers the field

this also corrects any bugs related to not filling in request structures, because the new helper always fully writes to the struct. πŸŽ€

  1. userspace can provide a shorter or longer response struct. if it's shorter, the kernel reply gets truncated. the kernel should be designed to not write to new reply fields unless userspace has affirmatively requested them. periodt.

if the user buffer is longer, the kernel will zero-fill it.

userspace has three options to enable new response fields:

  • an output comp_mask that says the field is supported
  • look for non-zero values
  • infer the output must be valid because the request contents demand it, and old kernels will fail the request

the following helper functions implement these semantics πŸ‘‘

ib_copy_validate_udata_in β€” checks the minimum length, and the zero trailing:

struct driver_create_cq_req req;
int err;

err = ib_copy_validate_udata_in(udata, req, end_member);
if (err)
    return err;

the third argument specifies the last member of the struct in the first kernel version that introduced it, establishing the minimum required size. so it's the vibe check for "did you actually send me enough". πŸ’…

ib_copy_validate_udata_in_cm β€” the above, but it also validates that a comp_mask member only has supported bits set:

err = ib_copy_validate_udata_in_cm(udata, req, first_version_last_member,
                                   DRIVER_CREATE_CQ_MASK_FEATURE_A |
                                   DRIVER_CREATE_CQ_MASK_FEATURE_B);

ib_respond_udata β€” implements the response rules:

struct driver_create_cq_resp resp = {};

resp.some_field = value;
return ib_respond_udata(udata, resp);

ib_is_udata_in_empty β€” use this instead of ib_copy_validate_udata_in if the driver doesn't have a request structure:

ret = ib_is_udata_in_empty(udata);
if (ret)
    return ret;

similarly, ib_respond_empty_udata is used instead of ib_respond_udata if the driver doesn't have a response structure:

return ib_respond_empty_udata(udata);

πŸ¦‹ SEE ALSO πŸ¦‹

kernel file ./include/rdma/ib_verbs.h and honestly a whole friend group of manpages went here:


bestie reminder: those compatibility rules are the whole personality of this struct. longer request β†’ trailing unknown bytes must be all zeros, shorter request β†’ kernel zero-pads, and the kernel shouldn't touch new reply fields unless userspace affirmatively asked. respect the rules and everything slays πŸ’–

and that's the whole page, mwah πŸ’‹ β€” sourced from ./include/rdma, dated October 2026, filed under struct ib_udata(9). go forth and comp_mask responsibly, ily πŸŽ€πŸŒˆπŸ‘‘

πŸ“¦ where this page comes from