drivers/infiniband/core/mad_rmpp.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/core/mad_rmpp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/core/mad_rmpp.c- Extension
.c- Size
- 28429 bytes
- Lines
- 968
- Domain
- Driver Families
- Bucket
- drivers/infiniband
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/slab.hmad_priv.hmad_rmpp.h
Detected Declarations
struct mad_rmpp_recvenum rmpp_statefunction deref_rmpp_recvfunction destroy_rmpp_recvfunction ib_cancel_rmpp_recvsfunction list_for_each_entry_safefunction format_ackfunction ack_recvfunction ack_ds_ackfunction ib_rmpp_send_handlerfunction nack_recvfunction recv_timeout_handlerfunction recv_cleanup_handlerfunction create_rmpp_recvfunction find_rmpp_recvfunction list_for_each_entryfunction acquire_rmpp_recvfunction insert_rmpp_recvfunction get_last_flagfunction get_seg_numfunction window_sizefunction list_for_each_entry_reversefunction update_seg_numfunction get_mad_lenfunction continue_rmppfunction start_rmppfunction send_next_segfunction abort_sendfunction adjust_last_ackfunction process_ds_ackfunction process_rmpp_ackfunction process_rmpp_datafunction process_rmpp_stopfunction process_rmpp_abortfunction ib_process_rmpp_recv_wcfunction init_newwinfunction ib_send_rmpp_madfunction ib_process_rmpp_send_wcfunction ib_retry_rmpp
Annotated Snippet
struct mad_rmpp_recv {
struct ib_mad_agent_private *agent;
struct list_head list;
struct delayed_work timeout_work;
struct delayed_work cleanup_work;
struct completion comp;
enum rmpp_state state;
spinlock_t lock;
refcount_t refcount;
struct ib_ah *ah;
struct ib_mad_recv_wc *rmpp_wc;
struct ib_mad_recv_buf *cur_seg_buf;
int last_ack;
int seg_num;
int newwin;
int repwin;
__be64 tid;
u32 src_qp;
u32 slid;
u8 mgmt_class;
u8 class_version;
u8 method;
u8 base_version;
};
static inline void deref_rmpp_recv(struct mad_rmpp_recv *rmpp_recv)
{
if (refcount_dec_and_test(&rmpp_recv->refcount))
complete(&rmpp_recv->comp);
}
static void destroy_rmpp_recv(struct mad_rmpp_recv *rmpp_recv)
{
deref_rmpp_recv(rmpp_recv);
wait_for_completion(&rmpp_recv->comp);
rdma_destroy_ah(rmpp_recv->ah, RDMA_DESTROY_AH_SLEEPABLE);
kfree(rmpp_recv);
}
void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent)
{
struct mad_rmpp_recv *rmpp_recv, *temp_rmpp_recv;
unsigned long flags;
spin_lock_irqsave(&agent->lock, flags);
list_for_each_entry(rmpp_recv, &agent->rmpp_list, list) {
cancel_delayed_work(&rmpp_recv->timeout_work);
cancel_delayed_work(&rmpp_recv->cleanup_work);
}
spin_unlock_irqrestore(&agent->lock, flags);
flush_workqueue(agent->qp_info->port_priv->wq);
list_for_each_entry_safe(rmpp_recv, temp_rmpp_recv,
&agent->rmpp_list, list) {
list_del(&rmpp_recv->list);
if (rmpp_recv->state != RMPP_STATE_COMPLETE)
ib_free_recv_mad(rmpp_recv->rmpp_wc);
destroy_rmpp_recv(rmpp_recv);
}
}
static void format_ack(struct ib_mad_send_buf *msg,
struct ib_rmpp_mad *data,
struct mad_rmpp_recv *rmpp_recv)
{
struct ib_rmpp_mad *ack = msg->mad;
unsigned long flags;
memcpy(ack, &data->mad_hdr, msg->hdr_len);
ack->mad_hdr.method ^= IB_MGMT_METHOD_RESP;
ack->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_ACK;
ib_set_rmpp_flags(&ack->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE);
spin_lock_irqsave(&rmpp_recv->lock, flags);
rmpp_recv->last_ack = rmpp_recv->seg_num;
ack->rmpp_hdr.seg_num = cpu_to_be32(rmpp_recv->seg_num);
ack->rmpp_hdr.paylen_newwin = cpu_to_be32(rmpp_recv->newwin);
spin_unlock_irqrestore(&rmpp_recv->lock, flags);
}
static void ack_recv(struct mad_rmpp_recv *rmpp_recv,
struct ib_mad_recv_wc *recv_wc)
{
struct ib_mad_send_buf *msg;
int ret, hdr_len;
Annotation
- Immediate include surface: `linux/slab.h`, `mad_priv.h`, `mad_rmpp.h`.
- Detected declarations: `struct mad_rmpp_recv`, `enum rmpp_state`, `function deref_rmpp_recv`, `function destroy_rmpp_recv`, `function ib_cancel_rmpp_recvs`, `function list_for_each_entry_safe`, `function format_ack`, `function ack_recv`, `function ack_ds_ack`, `function ib_rmpp_send_handler`.
- Atlas domain: Driver Families / drivers/infiniband.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.