drivers/infiniband/core/iwpm_util.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/core/iwpm_util.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/core/iwpm_util.c
Extension
.c
Size
22059 bytes
Lines
794
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (hash_bucket_head) {
			hlist_add_head(&map_info->hlist_node, hash_bucket_head);
			ret = 0;
		}
	}
	spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags);

	if (!hash_bucket_head)
		kfree(map_info);
	return ret;
}

/**
 * iwpm_remove_mapinfo - Remove local and mapped IPv4/IPv6 address
 *                       info from the hash table
 * @local_sockaddr: Local ip/tcp address
 * @mapped_local_addr: Mapped local ip/tcp address
 *
 * Returns err code if mapping info is not found in the hash table,
 * otherwise returns 0
 */
int iwpm_remove_mapinfo(struct sockaddr_storage *local_sockaddr,
			struct sockaddr_storage *mapped_local_addr)
{
	struct hlist_node *tmp_hlist_node;
	struct hlist_head *hash_bucket_head;
	struct iwpm_mapping_info *map_info = NULL;
	unsigned long flags;
	int ret = -EINVAL;

	spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
	if (iwpm_hash_bucket) {
		hash_bucket_head = get_mapinfo_hash_bucket(
					local_sockaddr,
					mapped_local_addr);
		if (!hash_bucket_head)
			goto remove_mapinfo_exit;

		hlist_for_each_entry_safe(map_info, tmp_hlist_node,
					hash_bucket_head, hlist_node) {

			if (!iwpm_compare_sockaddr(&map_info->mapped_sockaddr,
						mapped_local_addr)) {

				hlist_del_init(&map_info->hlist_node);
				kfree(map_info);
				ret = 0;
				break;
			}
		}
	}
remove_mapinfo_exit:
	spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags);
	return ret;
}

static void free_hash_bucket(void)
{
	struct hlist_node *tmp_hlist_node;
	struct iwpm_mapping_info *map_info;
	unsigned long flags;
	int i;

	/* remove all the mapinfo data from the list */
	spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
	for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) {
		hlist_for_each_entry_safe(map_info, tmp_hlist_node,
			&iwpm_hash_bucket[i], hlist_node) {

				hlist_del_init(&map_info->hlist_node);
				kfree(map_info);
			}
	}
	/* free the hash list */
	kfree(iwpm_hash_bucket);
	iwpm_hash_bucket = NULL;
	spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags);
}

static void free_reminfo_bucket(void)
{
	struct hlist_node *tmp_hlist_node;
	struct iwpm_remote_info *rem_info;
	unsigned long flags;
	int i;

	/* remove all the remote info from the list */
	spin_lock_irqsave(&iwpm_reminfo_lock, flags);
	for (i = 0; i < IWPM_REMINFO_HASH_SIZE; i++) {
		hlist_for_each_entry_safe(rem_info, tmp_hlist_node,

Annotation

Implementation Notes