net/core/sock.c

Source file repositories/reference/linux-study-clean/net/core/sock.c

File Facts

System
Linux kernel
Corpus path
net/core/sock.c
Extension
.c
Size
115318 bytes
Lines
4613
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

const struct proto_ops *ops = READ_ONCE(sock->ops);

		if (ops->set_rcvbuf)
			ops->set_rcvbuf(sk, sk->sk_rcvbuf);
	}
}

void sock_set_rcvbuf(struct sock *sk, int val)
{
	lock_sock(sk);
	__sock_set_rcvbuf(sk, val);
	release_sock(sk);
}
EXPORT_SYMBOL(sock_set_rcvbuf);

static void __sock_set_mark(struct sock *sk, u32 val)
{
	if (val != sk->sk_mark) {
		WRITE_ONCE(sk->sk_mark, val);
		sk_dst_reset(sk);
	}
}

void sock_set_mark(struct sock *sk, u32 val)
{
	lock_sock(sk);
	__sock_set_mark(sk, val);
	release_sock(sk);
}
EXPORT_SYMBOL(sock_set_mark);

static void sock_release_reserved_memory(struct sock *sk, int bytes)
{
	/* Round down bytes to multiple of pages */
	bytes = round_down(bytes, PAGE_SIZE);

	WARN_ON(bytes > sk->sk_reserved_mem);
	WRITE_ONCE(sk->sk_reserved_mem, sk->sk_reserved_mem - bytes);
	sk_mem_reclaim(sk);
}

static int sock_reserve_memory(struct sock *sk, int bytes)
{
	long allocated;
	bool charged;
	int pages;

	if (!mem_cgroup_sk_enabled(sk) || !sk_has_account(sk))
		return -EOPNOTSUPP;

	if (!bytes)
		return 0;

	pages = sk_mem_pages(bytes);

	/* pre-charge to memcg */
	charged = mem_cgroup_sk_charge(sk, pages,
				       GFP_KERNEL | __GFP_RETRY_MAYFAIL);
	if (!charged)
		return -ENOMEM;

	if (sk->sk_bypass_prot_mem)
		goto success;

	/* pre-charge to forward_alloc */
	sk_memory_allocated_add(sk, pages);
	allocated = sk_memory_allocated(sk);

	/* If the system goes into memory pressure with this
	 * precharge, give up and return error.
	 */
	if (allocated > sk_prot_mem_limits(sk, 1)) {
		sk_memory_allocated_sub(sk, pages);
		mem_cgroup_sk_uncharge(sk, pages);
		return -ENOMEM;
	}

success:
	sk_forward_alloc_add(sk, pages << PAGE_SHIFT);

	WRITE_ONCE(sk->sk_reserved_mem,
		   sk->sk_reserved_mem + (pages << PAGE_SHIFT));

	return 0;
}

#ifdef CONFIG_PAGE_POOL

/* This is the number of tokens and frags that the user can SO_DEVMEM_DONTNEED
 * in 1 syscall. The limit exists to limit the amount of memory the kernel

Annotation

Implementation Notes