drivers/infiniband/hw/hns/hns_roce_bond.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/hns/hns_roce_bond.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/hw/hns/hns_roce_bond.c- Extension
.c- Size
- 25128 bytes
- Lines
- 1013
- 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
net/lag.hnet/bonding.hhns_roce_device.hhns_roce_hw_v2.hhns_roce_bond.h
Detected Declarations
function get_netdev_bond_slave_idfunction hns_roce_set_bond_netdevfunction hns_roce_bond_is_activefunction hns_roce_bond_get_active_slavefunction hns_roce_recover_bondfunction hns_roce_slave_uninitfunction switch_main_devfunction dealloc_die_infofunction alloc_bond_idfunction remove_bond_idfunction hns_roce_set_bondfunction hns_roce_clear_bondfunction hns_roce_slave_changestatefunction hns_roce_slave_change_numfunction hns_roce_bond_info_update_nolockfunction is_dev_bond_supportedfunction check_slave_supportfunction hns_roce_bond_workfunction hns_roce_attach_bond_grpfunction hns_roce_detach_bond_grpfunction hns_roce_cleanup_bondfunction lowerstate_event_filterfunction lowerstate_event_settingfunction hns_roce_bond_lowerstate_eventfunction is_bond_setting_supportedfunction upper_event_settingfunction check_unlinking_bond_supportfunction check_linking_bond_supportfunction check_bond_supportfunction upper_event_filterfunction hns_roce_bond_upper_eventfunction hns_roce_bond_eventfunction hns_roce_alloc_bond_grpfunction hns_roce_dealloc_bond_grpfunction xa_for_eachfunction hns_roce_bond_initfunction hns_roce_bond_suspendfunction hns_roce_bond_resume
Annotated Snippet
if (bond_grp->upper_dev) {
upper_dev = get_upper_dev_from_ndev(net_dev);
if (bond_grp->upper_dev == upper_dev) {
dev_put(upper_dev);
return bond_grp;
}
dev_put(upper_dev);
}
}
return NULL;
}
static int hns_roce_set_bond_netdev(struct hns_roce_bond_group *bond_grp,
struct hns_roce_dev *hr_dev)
{
struct net_device *active_dev;
struct net_device *old_dev;
int i, ret = 0;
if (bond_grp->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP) {
rcu_read_lock();
active_dev =
bond_option_active_slave_get_rcu(netdev_priv(bond_grp->upper_dev));
rcu_read_unlock();
} else {
for (i = 0; i < ROCE_BOND_FUNC_MAX; i++) {
active_dev = bond_grp->bond_func_info[i].net_dev;
if (active_dev &&
ib_get_curr_port_state(active_dev) == IB_PORT_ACTIVE)
break;
}
}
if (!active_dev || i == ROCE_BOND_FUNC_MAX)
active_dev = get_hr_netdev(hr_dev, 0);
old_dev = ib_device_get_netdev(&hr_dev->ib_dev, 1);
if (old_dev == active_dev)
goto out;
ret = ib_device_set_netdev(&hr_dev->ib_dev, active_dev, 1);
if (ret) {
dev_err(hr_dev->dev, "failed to set netdev for bond.\n");
goto out;
}
if (bond_grp->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP) {
if (old_dev)
roce_del_all_netdev_gids(&hr_dev->ib_dev, 1, old_dev);
rdma_roce_rescan_port(&hr_dev->ib_dev, 1);
}
out:
dev_put(old_dev);
return ret;
}
bool hns_roce_bond_is_active(struct hns_roce_dev *hr_dev)
{
struct net_device *net_dev = get_hr_netdev(hr_dev, 0);
struct hns_roce_bond_group *bond_grp;
u8 bus_num = get_hr_bus_num(hr_dev);
bond_grp = hns_roce_get_bond_grp(net_dev, bus_num);
if (bond_grp && bond_grp->bond_state != HNS_ROCE_BOND_NOT_BONDED &&
bond_grp->bond_state != HNS_ROCE_BOND_NOT_ATTACHED)
return true;
return false;
}
static void hns_roce_bond_get_active_slave(struct hns_roce_bond_group *bond_grp)
{
struct net_device *net_dev;
u32 active_slave_map = 0;
u8 active_slave_num = 0;
bool active;
u8 i;
for (i = 0; i < ROCE_BOND_FUNC_MAX; i++) {
net_dev = bond_grp->bond_func_info[i].net_dev;
if (!net_dev || !(bond_grp->slave_map & (1U << i)))
continue;
active = (bond_grp->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP) ?
net_lag_port_dev_txable(net_dev) :
(ib_get_curr_port_state(net_dev) == IB_PORT_ACTIVE);
if (active) {
active_slave_num++;
active_slave_map |= (1U << i);
Annotation
- Immediate include surface: `net/lag.h`, `net/bonding.h`, `hns_roce_device.h`, `hns_roce_hw_v2.h`, `hns_roce_bond.h`.
- Detected declarations: `function get_netdev_bond_slave_id`, `function hns_roce_set_bond_netdev`, `function hns_roce_bond_is_active`, `function hns_roce_bond_get_active_slave`, `function hns_roce_recover_bond`, `function hns_roce_slave_uninit`, `function switch_main_dev`, `function dealloc_die_info`, `function alloc_bond_id`, `function remove_bond_id`.
- 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.