net/rds/ib_ring.c
Source file repositories/reference/linux-study-clean/net/rds/ib_ring.c
File Facts
- System
- Linux kernel
- Corpus path
net/rds/ib_ring.c- Extension
.c- Size
- 4915 bytes
- Lines
- 169
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: implementation source
- Status
- source implementation candidate
Why This File Exists
Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hrds.hib.h
Detected Declarations
function rds_ib_ring_initfunction __rds_ib_ring_usedfunction rds_ib_ring_resizefunction __rds_ib_ring_emptyfunction rds_ib_ring_allocfunction rds_ib_ring_freefunction rds_ib_ring_unallocfunction rds_ib_ring_emptyfunction rds_ib_ring_lowfunction rds_ib_ring_oldestfunction rds_ib_ring_completed
Annotated Snippet
#include <linux/kernel.h>
#include "rds.h"
#include "ib.h"
/*
* Locking for IB rings.
* We assume that allocation is always protected by a mutex
* in the caller (this is a valid assumption for the current
* implementation).
*
* Freeing always happens in an interrupt, and hence only
* races with allocations, but not with other free()s.
*
* The interaction between allocation and freeing is that
* the alloc code has to determine the number of free entries.
* To this end, we maintain two counters; an allocation counter
* and a free counter. Both are allowed to run freely, and wrap
* around.
* The number of used entries is always (alloc_ctr - free_ctr) % NR.
*
* The current implementation makes free_ctr atomic. When the
* caller finds an allocation fails, it should set an "alloc fail"
* bit and retry the allocation. The "alloc fail" bit essentially tells
* the CQ completion handlers to wake it up after freeing some
* more entries.
*/
/*
* This only happens on shutdown.
*/
DECLARE_WAIT_QUEUE_HEAD(rds_ib_ring_empty_wait);
void rds_ib_ring_init(struct rds_ib_work_ring *ring, u32 nr)
{
memset(ring, 0, sizeof(*ring));
ring->w_nr = nr;
rdsdebug("ring %p nr %u\n", ring, ring->w_nr);
}
static inline u32 __rds_ib_ring_used(struct rds_ib_work_ring *ring)
{
u32 diff;
/* This assumes that atomic_t has at least as many bits as u32 */
diff = ring->w_alloc_ctr - (u32) atomic_read(&ring->w_free_ctr);
BUG_ON(diff > ring->w_nr);
return diff;
}
void rds_ib_ring_resize(struct rds_ib_work_ring *ring, u32 nr)
{
/* We only ever get called from the connection setup code,
* prior to creating the QP. */
BUG_ON(__rds_ib_ring_used(ring));
ring->w_nr = nr;
}
static int __rds_ib_ring_empty(struct rds_ib_work_ring *ring)
{
return __rds_ib_ring_used(ring) == 0;
}
u32 rds_ib_ring_alloc(struct rds_ib_work_ring *ring, u32 val, u32 *pos)
{
u32 ret = 0, avail;
avail = ring->w_nr - __rds_ib_ring_used(ring);
rdsdebug("ring %p val %u next %u free %u\n", ring, val,
ring->w_alloc_ptr, avail);
if (val && avail) {
ret = min(val, avail);
*pos = ring->w_alloc_ptr;
ring->w_alloc_ptr = (ring->w_alloc_ptr + ret) % ring->w_nr;
ring->w_alloc_ctr += ret;
}
return ret;
}
void rds_ib_ring_free(struct rds_ib_work_ring *ring, u32 val)
{
ring->w_free_ptr = (ring->w_free_ptr + val) % ring->w_nr;
atomic_add(val, &ring->w_free_ctr);
if (__rds_ib_ring_empty(ring) &&
Annotation
- Immediate include surface: `linux/kernel.h`, `rds.h`, `ib.h`.
- Detected declarations: `function rds_ib_ring_init`, `function __rds_ib_ring_used`, `function rds_ib_ring_resize`, `function __rds_ib_ring_empty`, `function rds_ib_ring_alloc`, `function rds_ib_ring_free`, `function rds_ib_ring_unalloc`, `function rds_ib_ring_empty`, `function rds_ib_ring_low`, `function rds_ib_ring_oldest`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- 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.