Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 86c1aee1 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'listener_refactor_part_15'



Eric Dumazet says:

====================
tcp listener refactoring part 15

I am trying to make the final patch pushing request socks into ehash
as small as possible. In this patch series, I made various adjustments
for the SYNACK generation, allowing me to reach 1 Mpps SYNACK in my
stress test (still hitting LISTENER spinlock of course, and the syn_wait
spinlock)

I also converted the ICMP handlers a bit ahead of time :

They no longer need to get the LISTENER socket, and can use
only a lookup in ehash table. No big deal if we ignore ICMP
for requests socks before the final steps.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c9231f82 52036a43
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ enum dccp_state {
	DCCP_CLOSING	     = TCP_CLOSING,
	DCCP_TIME_WAIT	     = TCP_TIME_WAIT,
	DCCP_CLOSED	     = TCP_CLOSE,
	DCCP_NEW_SYN_RECV    = TCP_NEW_SYN_RECV,
	DCCP_PARTOPEN	     = TCP_MAX_STATES,
	DCCP_PASSIVE_CLOSEREQ,			/* clients receiving CloseReq */
	DCCP_MAX_STATES
@@ -57,6 +58,7 @@ enum {
	DCCPF_CLOSING	      = TCPF_CLOSING,
	DCCPF_TIME_WAIT	      = TCPF_TIME_WAIT,
	DCCPF_CLOSED	      = TCPF_CLOSE,
	DCCPF_NEW_SYN_RECV    = TCPF_NEW_SYN_RECV,
	DCCPF_PARTOPEN	      = (1 << DCCP_PARTOPEN),
};

@@ -317,6 +319,6 @@ static inline const char *dccp_role(const struct sock *sk)
	return NULL;
}

extern void dccp_syn_ack_timeout(struct sock *sk, struct request_sock *req);
extern void dccp_syn_ack_timeout(const struct request_sock *req);

#endif /* _LINUX_DCCP_H */
+4 −10
Original line number Diff line number Diff line
@@ -39,8 +39,7 @@ struct request_sock_ops {
	void		(*send_reset)(struct sock *sk,
				      struct sk_buff *skb);
	void		(*destructor)(struct request_sock *req);
	void		(*syn_ack_timeout)(struct sock *sk,
					   struct request_sock *req);
	void		(*syn_ack_timeout)(const struct request_sock *req);
};

int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req);
@@ -174,11 +173,6 @@ struct fastopen_queue {
 * %syn_wait_lock is necessary only to avoid proc interface having to grab the main
 * lock sock while browsing the listening hash (otherwise it's deadlock prone).
 *
 * This lock is acquired in read mode only from listening_get_next() seq_file
 * op and it's acquired in write mode _only_ from code that is actively
 * changing rskq_accept_head. All readers that are holding the master sock lock
 * don't need to grab this lock in read mode too as rskq_accept_head. writes
 * are always protected from the main sock lock.
 */
struct request_sock_queue {
	struct request_sock	*rskq_accept_head;
@@ -193,7 +187,7 @@ struct request_sock_queue {
					     */

	/* temporary alignment, our goal is to get rid of this lock */
	rwlock_t		syn_wait_lock ____cacheline_aligned_in_smp;
	spinlock_t		syn_wait_lock ____cacheline_aligned_in_smp;
};

int reqsk_queue_alloc(struct request_sock_queue *queue,
@@ -224,14 +218,14 @@ static inline void reqsk_queue_unlink(struct request_sock_queue *queue,
	struct listen_sock *lopt = queue->listen_opt;
	struct request_sock **prev;

	write_lock(&queue->syn_wait_lock);
	spin_lock(&queue->syn_wait_lock);

	prev = &lopt->syn_table[req->rsk_hash];
	while (*prev != req)
		prev = &(*prev)->dl_next;
	*prev = req->dl_next;

	write_unlock(&queue->syn_wait_lock);
	spin_unlock(&queue->syn_wait_lock);
	if (del_timer(&req->rsk_timer))
		reqsk_put(req);
}
+2 −1
Original line number Diff line number Diff line
@@ -433,7 +433,7 @@ int compat_tcp_getsockopt(struct sock *sk, int level, int optname,
int compat_tcp_setsockopt(struct sock *sk, int level, int optname,
			  char __user *optval, unsigned int optlen);
void tcp_set_keepalive(struct sock *sk, int val);
void tcp_syn_ack_timeout(struct sock *sk, struct request_sock *req);
void tcp_syn_ack_timeout(const struct request_sock *req);
int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
		int flags, int *addr_len);
void tcp_parse_options(const struct sk_buff *skb,
@@ -447,6 +447,7 @@ const u8 *tcp_parse_md5sig_option(const struct tcphdr *th);

void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb);
void tcp_v4_mtu_reduced(struct sock *sk);
void tcp_req_err(struct sock *sk, u32 seq);
int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb);
struct sock *tcp_create_openreq_child(struct sock *sk,
				      struct request_sock *req,
+7 −7
Original line number Diff line number Diff line
@@ -58,14 +58,14 @@ int reqsk_queue_alloc(struct request_sock_queue *queue,
		return -ENOMEM;

	get_random_bytes(&lopt->hash_rnd, sizeof(lopt->hash_rnd));
	rwlock_init(&queue->syn_wait_lock);
	spin_lock_init(&queue->syn_wait_lock);
	queue->rskq_accept_head = NULL;
	lopt->nr_table_entries = nr_table_entries;
	lopt->max_qlen_log = ilog2(nr_table_entries);

	write_lock_bh(&queue->syn_wait_lock);
	spin_lock_bh(&queue->syn_wait_lock);
	queue->listen_opt = lopt;
	write_unlock_bh(&queue->syn_wait_lock);
	spin_unlock_bh(&queue->syn_wait_lock);

	return 0;
}
@@ -81,10 +81,10 @@ static inline struct listen_sock *reqsk_queue_yank_listen_sk(
{
	struct listen_sock *lopt;

	write_lock_bh(&queue->syn_wait_lock);
	spin_lock_bh(&queue->syn_wait_lock);
	lopt = queue->listen_opt;
	queue->listen_opt = NULL;
	write_unlock_bh(&queue->syn_wait_lock);
	spin_unlock_bh(&queue->syn_wait_lock);

	return lopt;
}
@@ -100,7 +100,7 @@ void reqsk_queue_destroy(struct request_sock_queue *queue)
		for (i = 0; i < lopt->nr_table_entries; i++) {
			struct request_sock *req;

			write_lock_bh(&queue->syn_wait_lock);
			spin_lock_bh(&queue->syn_wait_lock);
			while ((req = lopt->syn_table[i]) != NULL) {
				lopt->syn_table[i] = req->dl_next;
				atomic_inc(&lopt->qlen_dec);
@@ -108,7 +108,7 @@ void reqsk_queue_destroy(struct request_sock_queue *queue)
					reqsk_put(req);
				reqsk_put(req);
			}
			write_unlock_bh(&queue->syn_wait_lock);
			spin_unlock_bh(&queue->syn_wait_lock);
		}
	}

+1 −0
Original line number Diff line number Diff line
@@ -317,6 +317,7 @@ int inet_dccp_listen(struct socket *sock, int backlog);
unsigned int dccp_poll(struct file *file, struct socket *sock,
		       poll_table *wait);
int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);
void dccp_req_err(struct sock *sk, u64 seq);

struct sk_buff *dccp_ctl_make_reset(struct sock *sk, struct sk_buff *skb);
int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code);
Loading