提交 f9f265f3 编写于 作者: L Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm:
  dlm: sanitize work_start() in lowcomms.c
  dlm: reduce cond_resched during send
  dlm: use TCP_NODELAY
  dlm: Use cmwq for send and receive workqueues
  dlm: Handle application limited situations properly.
...@@ -63,6 +63,9 @@ ...@@ -63,6 +63,9 @@
#define NEEDED_RMEM (4*1024*1024) #define NEEDED_RMEM (4*1024*1024)
#define CONN_HASH_SIZE 32 #define CONN_HASH_SIZE 32
/* Number of messages to send before rescheduling */
#define MAX_SEND_MSG_COUNT 25
struct cbuf { struct cbuf {
unsigned int base; unsigned int base;
unsigned int len; unsigned int len;
...@@ -108,6 +111,7 @@ struct connection { ...@@ -108,6 +111,7 @@ struct connection {
#define CF_INIT_PENDING 4 #define CF_INIT_PENDING 4
#define CF_IS_OTHERCON 5 #define CF_IS_OTHERCON 5
#define CF_CLOSE 6 #define CF_CLOSE 6
#define CF_APP_LIMITED 7
struct list_head writequeue; /* List of outgoing writequeue_entries */ struct list_head writequeue; /* List of outgoing writequeue_entries */
spinlock_t writequeue_lock; spinlock_t writequeue_lock;
int (*rx_action) (struct connection *); /* What to do when active */ int (*rx_action) (struct connection *); /* What to do when active */
...@@ -295,7 +299,17 @@ static void lowcomms_write_space(struct sock *sk) ...@@ -295,7 +299,17 @@ static void lowcomms_write_space(struct sock *sk)
{ {
struct connection *con = sock2con(sk); struct connection *con = sock2con(sk);
if (con && !test_and_set_bit(CF_WRITE_PENDING, &con->flags)) if (!con)
return;
clear_bit(SOCK_NOSPACE, &con->sock->flags);
if (test_and_clear_bit(CF_APP_LIMITED, &con->flags)) {
con->sock->sk->sk_write_pending--;
clear_bit(SOCK_ASYNC_NOSPACE, &con->sock->flags);
}
if (!test_and_set_bit(CF_WRITE_PENDING, &con->flags))
queue_work(send_workqueue, &con->swork); queue_work(send_workqueue, &con->swork);
} }
...@@ -915,6 +929,7 @@ static void tcp_connect_to_sock(struct connection *con) ...@@ -915,6 +929,7 @@ static void tcp_connect_to_sock(struct connection *con)
struct sockaddr_storage saddr, src_addr; struct sockaddr_storage saddr, src_addr;
int addr_len; int addr_len;
struct socket *sock = NULL; struct socket *sock = NULL;
int one = 1;
if (con->nodeid == 0) { if (con->nodeid == 0) {
log_print("attempt to connect sock 0 foiled"); log_print("attempt to connect sock 0 foiled");
...@@ -960,6 +975,11 @@ static void tcp_connect_to_sock(struct connection *con) ...@@ -960,6 +975,11 @@ static void tcp_connect_to_sock(struct connection *con)
make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len); make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len);
log_print("connecting to %d", con->nodeid); log_print("connecting to %d", con->nodeid);
/* Turn off Nagle's algorithm */
kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&one,
sizeof(one));
result = result =
sock->ops->connect(sock, (struct sockaddr *)&saddr, addr_len, sock->ops->connect(sock, (struct sockaddr *)&saddr, addr_len,
O_NONBLOCK); O_NONBLOCK);
...@@ -1011,6 +1031,10 @@ static struct socket *tcp_create_listen_sock(struct connection *con, ...@@ -1011,6 +1031,10 @@ static struct socket *tcp_create_listen_sock(struct connection *con,
goto create_out; goto create_out;
} }
/* Turn off Nagle's algorithm */
kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&one,
sizeof(one));
result = kernel_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, result = kernel_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(char *)&one, sizeof(one)); (char *)&one, sizeof(one));
...@@ -1297,6 +1321,7 @@ static void send_to_sock(struct connection *con) ...@@ -1297,6 +1321,7 @@ static void send_to_sock(struct connection *con)
const int msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL; const int msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
struct writequeue_entry *e; struct writequeue_entry *e;
int len, offset; int len, offset;
int count = 0;
mutex_lock(&con->sock_mutex); mutex_lock(&con->sock_mutex);
if (con->sock == NULL) if (con->sock == NULL)
...@@ -1319,14 +1344,27 @@ static void send_to_sock(struct connection *con) ...@@ -1319,14 +1344,27 @@ static void send_to_sock(struct connection *con)
ret = kernel_sendpage(con->sock, e->page, offset, len, ret = kernel_sendpage(con->sock, e->page, offset, len,
msg_flags); msg_flags);
if (ret == -EAGAIN || ret == 0) { if (ret == -EAGAIN || ret == 0) {
if (ret == -EAGAIN &&
test_bit(SOCK_ASYNC_NOSPACE, &con->sock->flags) &&
!test_and_set_bit(CF_APP_LIMITED, &con->flags)) {
/* Notify TCP that we're limited by the
* application window size.
*/
set_bit(SOCK_NOSPACE, &con->sock->flags);
con->sock->sk->sk_write_pending++;
}
cond_resched(); cond_resched();
goto out; goto out;
} }
if (ret <= 0) if (ret <= 0)
goto send_error; goto send_error;
} }
/* Don't starve people filling buffers */
/* Don't starve people filling buffers */
if (++count >= MAX_SEND_MSG_COUNT) {
cond_resched(); cond_resched();
count = 0;
}
spin_lock(&con->writequeue_lock); spin_lock(&con->writequeue_lock);
e->offset += ret; e->offset += ret;
...@@ -1430,20 +1468,19 @@ static void work_stop(void) ...@@ -1430,20 +1468,19 @@ static void work_stop(void)
static int work_start(void) static int work_start(void)
{ {
int error; recv_workqueue = alloc_workqueue("dlm_recv", WQ_MEM_RECLAIM |
recv_workqueue = create_workqueue("dlm_recv"); WQ_HIGHPRI | WQ_FREEZEABLE, 0);
error = IS_ERR(recv_workqueue); if (!recv_workqueue) {
if (error) { log_print("can't start dlm_recv");
log_print("can't start dlm_recv %d", error); return -ENOMEM;
return error;
} }
send_workqueue = create_singlethread_workqueue("dlm_send"); send_workqueue = alloc_workqueue("dlm_send", WQ_MEM_RECLAIM |
error = IS_ERR(send_workqueue); WQ_HIGHPRI | WQ_FREEZEABLE, 0);
if (error) { if (!send_workqueue) {
log_print("can't start dlm_send %d", error); log_print("can't start dlm_send");
destroy_workqueue(recv_workqueue); destroy_workqueue(recv_workqueue);
return error; return -ENOMEM;
} }
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册