STRUCT IB_UDATA(9)
π 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 dataoutlenβ 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:
- 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.
- 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
0for the new fields. the kernel has three options to enable new request fields:
- an input
comp_maskthat says the field is supported - look for non-zero values
- check if the
udata->inlensize 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. π
- 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_maskthat 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:
struct rdma_stat_desc(9),struct rdma_hw_stats(9),ib_rate_to_mult(9),ib_rate_to_mbps(9),ib_port_attr_to_speed_info(9),enum ib_mr_type(9),struct ib_mr_status(9),mult_to_ib_rate(9)struct rdma_netdev(9),struct ib_device_ops(9),ib_get_client_data(9),ib_modify_qp_is_ok(9)rdma_cap_ib_switch(9),rdma_start_port(9),rdma_for_each_port(9),rdma_end_port(9),rdma_cap_ib_mad(9),rdma_cap_opa_mad(9),rdma_cap_ib_smi(9),rdma_cap_ib_cm(9),rdma_cap_iw_cm(9),rdma_cap_ib_sa(9),rdma_cap_ib_mcast(9),rdma_cap_af_ib(9),rdma_cap_eth_ah(9),rdma_cap_opa_ah(9),rdma_max_mad_size(9),rdma_cap_roce_gid_table(9),rdma_core_cap_opa_port(9)rdma_mtu_enum_to_int(9),rdma_mtu_from_attr(9)ib_alloc_pd(9),ib_dealloc_pd(9),rdma_create_ah(9),rdma_create_user_ah(9),ib_get_gids_from_rdma_hdr(9),ib_get_rdma_header_version(9),ib_init_ah_attr_from_wc(9),ib_create_ah_from_wc(9),rdma_modify_ah(9),rdma_query_ah(9),rdma_destroy_ah_user(9),rdma_destroy_ah(9)ib_modify_srq(9),ib_query_srq(9),ib_destroy_srq_user(9),ib_destroy_srq(9),ib_post_srq_recv(9)ib_create_qp(9),ib_modify_qp_with_udata(9),ib_modify_qp(9),ib_query_qp(9),ib_destroy_qp(9),ib_open_qp(9),ib_close_qp(9),ib_post_send(9),ib_post_recv(9)ib_alloc_cq_any(9),rdma_set_cq_moderation(9),ib_destroy_cq_user(9),ib_destroy_cq(9),ib_poll_cq(9),ib_req_notify_cq(9)ib_virt_dma_to_ptr(9),ib_virt_dma_to_page(9),ib_dma_mapping_error(9),ib_dma_map_single(9),ib_dma_unmap_single(9),ib_dma_map_page(9),ib_dma_unmap_page(9),ib_dma_map_bvec(9),ib_dma_unmap_bvec(9),ib_dma_map_sgtable_attrs(9),ib_dma_map_sg(9),ib_dma_unmap_sg(9),ib_dma_max_seg_size(9),ib_dma_sync_single_for_cpu(9),ib_dma_sync_single_for_device(9)ib_dereg_mr_user(9),ib_dereg_mr(9),ib_update_fast_reg_key(9),ib_inc_rkey(9),ib_attach_mcast(9),ib_detach_mcast(9),ib_check_mr_status(9)ib_device_try_get(9),rdma_ah_find_type(9),ib_lid_cpu16(9),ib_lid_be16(9),rdma_roce_rescan_device(9),rdma_device_to_ibdev(9),ibdev_to_node(9),rdma_device_to_drv_device(9),rdma_flow_label_to_udp_sport(9),rdma_calc_flow_label(9),rdma_get_udp_sport(9)
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
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms