forked from mirrors/linux
		
	ethtool: add header/data split indication
For applications running on a mix of platforms it's useful to have a clear indication whether host's NIC supports the geometry requirements of TCP zero-copy. TCP zero-copy Rx requires data to be neatly placed into memory pages. Most NICs can't do that. This patch is adding GET support only, since the NICs I work with either always have the feature enabled or enable it whenever MTU is set to jumbo. In other words I don't need SET. But adding set should be trivial. (The only note on SET is that we will likely want the setting to be "sticky" and use 0 / `unknown` to reset it back to driver default.) Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									1a918a32cd
								
							
						
					
					
						commit
						9690ae6042
					
				
					 4 changed files with 27 additions and 5 deletions
				
			
		|  | @ -860,8 +860,16 @@ Kernel response contents: | ||||||
|   ``ETHTOOL_A_RINGS_RX_JUMBO``          u32     size of RX jumbo ring |   ``ETHTOOL_A_RINGS_RX_JUMBO``          u32     size of RX jumbo ring | ||||||
|   ``ETHTOOL_A_RINGS_TX``                u32     size of TX ring |   ``ETHTOOL_A_RINGS_TX``                u32     size of TX ring | ||||||
|   ``ETHTOOL_A_RINGS_RX_BUF_LEN``        u32     size of buffers on the ring |   ``ETHTOOL_A_RINGS_RX_BUF_LEN``        u32     size of buffers on the ring | ||||||
|  |   ``ETHTOOL_A_RINGS_TCP_DATA_SPLIT``    u8      TCP header / data split | ||||||
|   ====================================  ======  =========================== |   ====================================  ======  =========================== | ||||||
| 
 | 
 | ||||||
|  | ``ETHTOOL_A_RINGS_TCP_DATA_SPLIT`` indicates whether the device is usable with | ||||||
|  | page-flipping TCP zero-copy receive (``getsockopt(TCP_ZEROCOPY_RECEIVE)``). | ||||||
|  | If enabled the device is configured to place frame headers and data into | ||||||
|  | separate buffers. The device configuration must make it possible to receive | ||||||
|  | full memory pages of data, for example because MTU is high enough or through | ||||||
|  | HW-GRO. | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| RINGS_SET | RINGS_SET | ||||||
| ========= | ========= | ||||||
|  |  | ||||||
|  | @ -70,9 +70,11 @@ enum { | ||||||
| /**
 | /**
 | ||||||
|  * struct kernel_ethtool_ringparam - RX/TX ring configuration |  * struct kernel_ethtool_ringparam - RX/TX ring configuration | ||||||
|  * @rx_buf_len: Current length of buffers on the rx ring. |  * @rx_buf_len: Current length of buffers on the rx ring. | ||||||
|  |  * @tcp_data_split: Scatter packet headers and data to separate buffers | ||||||
|  */ |  */ | ||||||
| struct kernel_ethtool_ringparam { | struct kernel_ethtool_ringparam { | ||||||
| 	u32	rx_buf_len; | 	u32	rx_buf_len; | ||||||
|  | 	u8	tcp_data_split; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  |  | ||||||
|  | @ -318,6 +318,12 @@ enum { | ||||||
| 
 | 
 | ||||||
| /* RINGS */ | /* RINGS */ | ||||||
| 
 | 
 | ||||||
|  | enum { | ||||||
|  | 	ETHTOOL_TCP_DATA_SPLIT_UNKNOWN = 0, | ||||||
|  | 	ETHTOOL_TCP_DATA_SPLIT_DISABLED, | ||||||
|  | 	ETHTOOL_TCP_DATA_SPLIT_ENABLED, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| enum { | enum { | ||||||
| 	ETHTOOL_A_RINGS_UNSPEC, | 	ETHTOOL_A_RINGS_UNSPEC, | ||||||
| 	ETHTOOL_A_RINGS_HEADER,				/* nest - _A_HEADER_* */ | 	ETHTOOL_A_RINGS_HEADER,				/* nest - _A_HEADER_* */ | ||||||
|  | @ -330,6 +336,7 @@ enum { | ||||||
| 	ETHTOOL_A_RINGS_RX_JUMBO,			/* u32 */ | 	ETHTOOL_A_RINGS_RX_JUMBO,			/* u32 */ | ||||||
| 	ETHTOOL_A_RINGS_TX,				/* u32 */ | 	ETHTOOL_A_RINGS_TX,				/* u32 */ | ||||||
| 	ETHTOOL_A_RINGS_RX_BUF_LEN,                     /* u32 */ | 	ETHTOOL_A_RINGS_RX_BUF_LEN,                     /* u32 */ | ||||||
|  | 	ETHTOOL_A_RINGS_TCP_DATA_SPLIT,			/* u8 */ | ||||||
| 
 | 
 | ||||||
| 	/* add new constants above here */ | 	/* add new constants above here */ | ||||||
| 	__ETHTOOL_A_RINGS_CNT, | 	__ETHTOOL_A_RINGS_CNT, | ||||||
|  |  | ||||||
|  | @ -53,7 +53,8 @@ static int rings_reply_size(const struct ethnl_req_info *req_base, | ||||||
| 	       nla_total_size(sizeof(u32)) +	/* _RINGS_RX_MINI */ | 	       nla_total_size(sizeof(u32)) +	/* _RINGS_RX_MINI */ | ||||||
| 	       nla_total_size(sizeof(u32)) +	/* _RINGS_RX_JUMBO */ | 	       nla_total_size(sizeof(u32)) +	/* _RINGS_RX_JUMBO */ | ||||||
| 	       nla_total_size(sizeof(u32)) +	/* _RINGS_TX */ | 	       nla_total_size(sizeof(u32)) +	/* _RINGS_TX */ | ||||||
| 	       nla_total_size(sizeof(u32));     /* _RINGS_RX_BUF_LEN */ | 	       nla_total_size(sizeof(u32)) +	/* _RINGS_RX_BUF_LEN */ | ||||||
|  | 	       nla_total_size(sizeof(u8));	/* _RINGS_TCP_DATA_SPLIT */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int rings_fill_reply(struct sk_buff *skb, | static int rings_fill_reply(struct sk_buff *skb, | ||||||
|  | @ -61,9 +62,11 @@ static int rings_fill_reply(struct sk_buff *skb, | ||||||
| 			    const struct ethnl_reply_data *reply_base) | 			    const struct ethnl_reply_data *reply_base) | ||||||
| { | { | ||||||
| 	const struct rings_reply_data *data = RINGS_REPDATA(reply_base); | 	const struct rings_reply_data *data = RINGS_REPDATA(reply_base); | ||||||
| 	const struct kernel_ethtool_ringparam *kernel_ringparam = &data->kernel_ringparam; | 	const struct kernel_ethtool_ringparam *kr = &data->kernel_ringparam; | ||||||
| 	const struct ethtool_ringparam *ringparam = &data->ringparam; | 	const struct ethtool_ringparam *ringparam = &data->ringparam; | ||||||
| 
 | 
 | ||||||
|  | 	WARN_ON(kr->tcp_data_split > ETHTOOL_TCP_DATA_SPLIT_ENABLED); | ||||||
|  | 
 | ||||||
| 	if ((ringparam->rx_max_pending && | 	if ((ringparam->rx_max_pending && | ||||||
| 	     (nla_put_u32(skb, ETHTOOL_A_RINGS_RX_MAX, | 	     (nla_put_u32(skb, ETHTOOL_A_RINGS_RX_MAX, | ||||||
| 			  ringparam->rx_max_pending) || | 			  ringparam->rx_max_pending) || | ||||||
|  | @ -84,9 +87,11 @@ static int rings_fill_reply(struct sk_buff *skb, | ||||||
| 			  ringparam->tx_max_pending) || | 			  ringparam->tx_max_pending) || | ||||||
| 	      nla_put_u32(skb, ETHTOOL_A_RINGS_TX, | 	      nla_put_u32(skb, ETHTOOL_A_RINGS_TX, | ||||||
| 			  ringparam->tx_pending)))  || | 			  ringparam->tx_pending)))  || | ||||||
| 	    (kernel_ringparam->rx_buf_len && | 	    (kr->rx_buf_len && | ||||||
| 	     (nla_put_u32(skb, ETHTOOL_A_RINGS_RX_BUF_LEN, | 	     (nla_put_u32(skb, ETHTOOL_A_RINGS_RX_BUF_LEN, kr->rx_buf_len))) || | ||||||
| 			  kernel_ringparam->rx_buf_len)))) | 	    (kr->tcp_data_split && | ||||||
|  | 	     (nla_put_u8(skb, ETHTOOL_A_RINGS_TCP_DATA_SPLIT, | ||||||
|  | 			 kr->tcp_data_split)))) | ||||||
| 		return -EMSGSIZE; | 		return -EMSGSIZE; | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Jakub Kicinski
						Jakub Kicinski