linux内核代码-注释详解:sock_init_data

/*\linux-5.10.x\net\core\sock.c
用于初始化套接字数据结构中的各个字段和锁,以及设置套接字的默认参数。具体功能如下:
	1、初始化套接字的读写锁和对等锁
	2、设置套接字的对等进程ID和对等进程凭证为NULL,并初始化对等锁
	3、设置套接字的待发送数据长度为0,接收缓冲区低水位标记为1,接收超时和发送超时为最大超时值
	4、设置套接字的时间戳为默认时间戳值
	5、如果BITS_PER_LONG的值是32,初始化套接字的时间戳序列锁
	6、设置套接字的零拷贝密钥为0
	7、如果配置了网络接收忙碌轮询功能,设置套接字的NAPI ID为0,并从系统变量中读取并设置套接字的忙碌轮询时间
	8、设置套接字的最大调度速率和调度速率为最大的无符号长整型值,调度速率的位移为10。将套接字的入站CPU设置为-1
	9、清除套接字的接收队列,删除所有已接收但尚未处理的数据包
*/
void sock_init_data(struct socket *sock, struct sock *sk)
{
	sk_init_common(sk);											//初始化通用的sock数据结构
	sk->sk_send_head	=	NULL;								//将发送队列头部指针置为空

	timer_setup(&sk->sk_timer, NULL, 0);						//设置定时器,使用空回调函数和初始超时值0

	sk->sk_allocation	=	GFP_KERNEL;							//设置当前socket的内存分配标志为内核级别的分配
	sk->sk_rcvbuf		=	READ_ONCE(sysctl_rmem_default);		//读取系统变量sysctl_rmem_default的值作为接收缓冲区大小
	sk->sk_sndbuf		=	READ_ONCE(sysctl_wmem_default);		//读取系统变量sysctl_wmem_default的值作为发送缓冲区大小
	sk->sk_state		=	TCP_CLOSE;							//设置socket状态为TCP_CLOSE,表示关闭状态
	sk_set_socket(sk, sock);									//将sock与sk关联起来

	sock_set_flag(sk, SOCK_ZAPPED);								//设置SOCK_ZAPPED标志位,表示socket被重置

	if (sock) {													//如果sock非空
		sk->sk_type	=	sock->type;								//将socket类型设置为sock的类型
		RCU_INIT_POINTER(sk->sk_wq, &sock->wq);					//将socket的等待队列指针赋给sk的等待队列指针
		sock->sk	=	sk;										//将sk赋给socket的sk字段
		sk->sk_uid	=	SOCK_INODE(sock)->i_uid;				//获取socket所属文件描述符的用户ID,并赋给sk的用户ID
	} else {													//如果sock为空
		RCU_INIT_POINTER(sk->sk_wq, NULL);						//初始化sk的等待队列指针为空
		sk->sk_uid	=	make_kuid(sock_net(sk)->user_ns, 0);	//将套接字的用户ID设置为make_kuid创建的内核用户ID(root用户ID)
	}

	rwlock_init(&sk->sk_callback_lock);							//对套接字的sk_callback_lock字段进行读写锁的初始化
	if (sk->sk_kern_sock)										//套接字是否为内核套接字(kern_sock)。kern_sock是一种特殊类型的套接字,它在内核空间中使用,与用户空间无关
		lockdep_set_class_and_name(								//lockdep_set_class_and_name用于设置锁的类和名称。是内核中的一个调试工具,用于跟踪锁的使用情况
			&sk->sk_callback_lock,								//要设置的锁对象
			af_kern_callback_keys + sk->sk_family,				
			af_family_kern_clock_key_strings[sk->sk_family]);	//将使用af_kern_callback_keys数组中与套接字家族(sk_family)相对应的元素作为锁类
	else														//如果套接字不是内核套接字
		lockdep_set_class_and_name(
			&sk->sk_callback_lock,
			af_callback_keys + sk->sk_family,
			af_family_clock_key_strings[sk->sk_family]);		//将使用af_callback_keys数组中与套接字家族(sk_family)相对应的元素作为锁类

	sk->sk_state_change	=	sock_def_wakeup;					//套接字状态改变的回调函数,当套接字状态发生改变时,将调用此函数
	sk->sk_data_ready	=	sock_def_readable;					//套接字数据就绪的回调函数,当套接字有数据可读时,将调用此函数
	sk->sk_write_space	=	sock_def_write_space;				//套接字写空间可用的回调函数,当套接字的写空间可用时,将调用此函数
	sk->sk_error_report	=	sock_def_error_report;				//套接字错误报告的回调函数,当套接字发生错误时,将调用此函数
	sk->sk_destruct		=	sock_def_destruct;					//套接字析构的回调函数,当套接字被销毁时,将调用此函数
	/* 以下字段用于在接收数据时进行分片处理 */
	sk->sk_frag.page	=	NULL;								//套接字的分段信息初始化为NULL
	sk->sk_frag.offset	=	0;									//偏移量为0
	sk->sk_peek_off		=	-1;									//查看偏移量设置为-1
	/* 以下字段和锁用于处理套接字的对等进程信息 */
	sk->sk_peer_pid 	=	NULL;								//对等进程ID字段
	sk->sk_peer_cred	=	NULL;								//对等进程凭证字段
	spin_lock_init(&sk->sk_peer_lock);							//对对等锁sk_peer_lock进行自旋锁的初始化
	/* 以下字段用于控制套接字的发送和接收行为 */
	sk->sk_write_pending	=	0;								//套接字的待发送数据长度字段
	sk->sk_rcvlowat		=	1;									//接收缓冲区低水位标记,表示最小可接收数据量
	sk->sk_rcvtimeo		=	MAX_SCHEDULE_TIMEOUT;				//接收超时字段设置为最大超时值(MAX_SCHEDULE_TIMEOUT)
	sk->sk_sndtimeo		=	MAX_SCHEDULE_TIMEOUT;				//发送超时字段设置为最大超时值(MAX_SCHEDULE_TIMEOUT)

	sk->sk_stamp = SK_DEFAULT_STAMP;							//套接字的时间戳设置为默认时间戳值。用于记录套接字的最后一次状态改变的时间
#if BITS_PER_LONG==32                                		 	// 如果每个长整型数占32位
		seqlock_init(&sk->sk_stamp_seq);				 		// 初始化套接字时间戳序列锁
#endif
	
	atomic_set(&sk->sk_zckey, 0);								// 设置套接字的零拷贝密钥为0
	
#ifdef CONFIG_NET_RX_BUSY_POLL
		sk->sk_napi_id = 0; 									// 网络适配器处理标识符初始化为0
		sk->sk_ll_usec = READ_ONCE(sysctl_net_busy_read);		// 读取网络繁忙忙等待时长
#endif
	/* 以下字段用于控制数据包的调度和处理 */
	sk->sk_max_pacing_rate = ~0UL;						 		// 设置套接字最大传输速率为最大值
	sk->sk_pacing_rate = ~0UL;							 		// 设置套接字传输速率为最大值
	WRITE_ONCE(sk->sk_pacing_shift, 10);				 		// 设置套接字传输速率控制参数为10
	sk->sk_incoming_cpu = -1;							 		// 设置套接字的所属CPU为-1,表示未分配CPU
	
	sk_rx_queue_clear(sk);								 		// 清空套接字的接收队列,这将删除所有已接收但尚未处理的数据包

	/*
	 * Before updating sk_refcnt, we must commit prior changes to memory
	 * (Documentation/RCU/rculist_nulls.rst for details)
	 */
	smp_wmb();													// 在多核系统中确保先前的写操作对于其他CPU可见
	refcount_set(&sk->sk_refcnt, 1);							// 设置套接字引用计数为1,表示有一个引用
	atomic_set(&sk->sk_drops, 0);								// 将套接字丢弃数据包计数器重置为0
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值