drivers/infiniband/ulp/srp/ib_srp.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/ulp/srp/ib_srp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/ulp/srp/ib_srp.c- Extension
.c- Size
- 112242 bytes
- Lines
- 4240
- Domain
- Driver Families
- Bucket
- drivers/infiniband
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/module.hlinux/hex.hlinux/init.hlinux/slab.hlinux/err.hlinux/string.hlinux/parser.hlinux/random.hlinux/jiffies.hlinux/lockdep.hlinux/inet.hnet/net_namespace.hrdma/ib_cache.hlinux/atomic.hscsi/scsi.hscsi/scsi_device.hscsi/scsi_dbg.hscsi/scsi_tcq.hscsi/srp.hscsi/scsi_transport_srp.hib_srp.h
Detected Declarations
struct srp_terminate_contextfunction srp_tmo_getfunction srp_tmo_setfunction srp_target_is_topspinfunction srp_free_iufunction srp_qp_eventfunction srp_init_ib_qpfunction srp_new_ib_cm_idfunction srp_new_rdma_cm_idfunction srp_new_cm_idfunction srp_destroy_fr_poolfunction srp_create_fr_poolfunction srp_fr_pool_getfunction srp_fr_pool_putfunction srp_destroy_qpfunction srp_create_ch_ibfunction srp_free_ch_ibfunction srp_path_rec_completionfunction srp_ib_lookup_pathfunction srp_rdma_lookup_pathfunction srp_lookup_pathfunction srp_get_subnet_timeoutfunction srp_send_reqfunction specificationfunction srp_queue_remove_workfunction srp_disconnect_targetfunction srp_exit_cmd_privfunction srp_init_cmd_privfunction srp_del_scsi_host_attrfunction srp_remove_targetfunction srp_remove_workfunction srp_rport_deletefunction srp_connected_chfunction srp_connect_chfunction srp_inv_rkey_err_donefunction srp_inv_rkeyfunction srp_unmap_datafunction srp_free_reqfunction srp_finish_reqfunction srp_terminate_cmdfunction srp_terminate_iofunction srp_max_it_iu_lenfunction srp_rport_reconnectfunction srp_map_descfunction srp_reg_mr_err_donefunction srp_map_finish_frfunction srp_map_sg_frfunction srp_map_sg_dma
Annotated Snippet
if (device_add(&host->dev))
goto put_host;
return host;
put_host:
put_device(&host->dev);
return NULL;
}
static void srp_rename_dev(struct ib_device *device, void *client_data)
{
struct srp_device *srp_dev = client_data;
struct srp_host *host, *tmp_host;
list_for_each_entry_safe(host, tmp_host, &srp_dev->dev_list, list) {
char name[IB_DEVICE_NAME_MAX + 8];
snprintf(name, sizeof(name), "srp-%s-%u",
dev_name(&device->dev), host->port);
device_rename(&host->dev, name);
}
}
static int srp_add_one(struct ib_device *device)
{
struct srp_device *srp_dev;
struct ib_device_attr *attr = &device->attrs;
struct srp_host *host;
int mr_page_shift;
u32 p;
u64 max_pages_per_mr;
unsigned int flags = 0;
srp_dev = kzalloc_obj(*srp_dev);
if (!srp_dev)
return -ENOMEM;
/*
* Use the smallest page size supported by the HCA, down to a
* minimum of 4096 bytes. We're unlikely to build large sglists
* out of smaller entries.
*/
mr_page_shift = max(12, ffs(attr->page_size_cap) - 1);
srp_dev->mr_page_size = 1 << mr_page_shift;
srp_dev->mr_page_mask = ~((u64) srp_dev->mr_page_size - 1);
max_pages_per_mr = attr->max_mr_size;
do_div(max_pages_per_mr, srp_dev->mr_page_size);
pr_debug("%s: %llu / %u = %llu <> %u\n", __func__,
attr->max_mr_size, srp_dev->mr_page_size,
max_pages_per_mr, SRP_MAX_PAGES_PER_MR);
srp_dev->max_pages_per_mr = min_t(u64, SRP_MAX_PAGES_PER_MR,
max_pages_per_mr);
srp_dev->has_fr = (attr->device_cap_flags &
IB_DEVICE_MEM_MGT_EXTENSIONS);
if (!never_register && !srp_dev->has_fr)
dev_warn(&device->dev, "FR is not supported\n");
else if (!never_register &&
attr->max_mr_size >= 2 * srp_dev->mr_page_size)
srp_dev->use_fast_reg = srp_dev->has_fr;
if (never_register || !register_always || !srp_dev->has_fr)
flags |= IB_PD_UNSAFE_GLOBAL_RKEY;
if (srp_dev->use_fast_reg) {
srp_dev->max_pages_per_mr =
min_t(u32, srp_dev->max_pages_per_mr,
attr->max_fast_reg_page_list_len);
}
srp_dev->mr_max_size = srp_dev->mr_page_size *
srp_dev->max_pages_per_mr;
pr_debug("%s: mr_page_shift = %d, device->max_mr_size = %#llx, device->max_fast_reg_page_list_len = %u, max_pages_per_mr = %d, mr_max_size = %#x\n",
dev_name(&device->dev), mr_page_shift, attr->max_mr_size,
attr->max_fast_reg_page_list_len,
srp_dev->max_pages_per_mr, srp_dev->mr_max_size);
INIT_LIST_HEAD(&srp_dev->dev_list);
srp_dev->dev = device;
srp_dev->pd = ib_alloc_pd(device, flags);
if (IS_ERR(srp_dev->pd)) {
int ret = PTR_ERR(srp_dev->pd);
kfree(srp_dev);
return ret;
}
if (flags & IB_PD_UNSAFE_GLOBAL_RKEY) {
srp_dev->global_rkey = srp_dev->pd->unsafe_global_rkey;
Annotation
- Immediate include surface: `linux/module.h`, `linux/hex.h`, `linux/init.h`, `linux/slab.h`, `linux/err.h`, `linux/string.h`, `linux/parser.h`, `linux/random.h`.
- Detected declarations: `struct srp_terminate_context`, `function srp_tmo_get`, `function srp_tmo_set`, `function srp_target_is_topspin`, `function srp_free_iu`, `function srp_qp_event`, `function srp_init_ib_qp`, `function srp_new_ib_cm_id`, `function srp_new_rdma_cm_id`, `function srp_new_cm_id`.
- Atlas domain: Driver Families / drivers/infiniband.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.