Skip to content

Commit 409e145

Browse files
committed
Merge branch 'tipc'
Eric Hugne says: ==================== tipc: refcount and memory leak fixes v3: Remove error logging from data path completely. Rebased on top of latest net merge. v2: Drop specific -ENOMEM logging in patch #1 (tipc: allow connection shutdown callback to be invoked in advance) And add a general error message if an internal server tries to send a message on a closed/nonexisting connection. In addition to the fix for refcount leak and memory leak during module removal, we also fix a problem where the topology server listening socket where unexpectedly closed. We also eliminate an unnecessary context switch during accept()/recvmsg() for nonblocking sockets. It might be good to include this patchset in stable aswell. After the v3 rebase on latest merge from net all patches apply cleanly on that tree. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 9e9cb62 + 2892505 commit 409e145

File tree

6 files changed

+47
-37
lines changed

6 files changed

+47
-37
lines changed

net/tipc/config.c

+2-7
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,6 @@ static void cfg_conn_msg_event(int conid, struct sockaddr_tipc *addr,
376376
struct tipc_cfg_msg_hdr *req_hdr;
377377
struct tipc_cfg_msg_hdr *rep_hdr;
378378
struct sk_buff *rep_buf;
379-
int ret;
380379

381380
/* Validate configuration message header (ignore invalid message) */
382381
req_hdr = (struct tipc_cfg_msg_hdr *)buf;
@@ -398,12 +397,8 @@ static void cfg_conn_msg_event(int conid, struct sockaddr_tipc *addr,
398397
memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr));
399398
rep_hdr->tcm_len = htonl(rep_buf->len);
400399
rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST);
401-
402-
ret = tipc_conn_sendmsg(&cfgsrv, conid, addr, rep_buf->data,
403-
rep_buf->len);
404-
if (ret < 0)
405-
pr_err("Sending cfg reply message failed, no memory\n");
406-
400+
tipc_conn_sendmsg(&cfgsrv, conid, addr, rep_buf->data,
401+
rep_buf->len);
407402
kfree_skb(rep_buf);
408403
}
409404
}

net/tipc/handler.c

-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ unsigned int tipc_k_signal(Handler routine, unsigned long argument)
5858

5959
spin_lock_bh(&qitem_lock);
6060
if (!handler_enabled) {
61-
pr_err("Signal request ignored by handler\n");
6261
spin_unlock_bh(&qitem_lock);
6362
return -ENOPROTOOPT;
6463
}

net/tipc/name_table.c

+34-3
Original file line numberDiff line numberDiff line change
@@ -941,17 +941,48 @@ int tipc_nametbl_init(void)
941941
return 0;
942942
}
943943

944+
/**
945+
* tipc_purge_publications - remove all publications for a given type
946+
*
947+
* tipc_nametbl_lock must be held when calling this function
948+
*/
949+
static void tipc_purge_publications(struct name_seq *seq)
950+
{
951+
struct publication *publ, *safe;
952+
struct sub_seq *sseq;
953+
struct name_info *info;
954+
955+
if (!seq->sseqs) {
956+
nameseq_delete_empty(seq);
957+
return;
958+
}
959+
sseq = seq->sseqs;
960+
info = sseq->info;
961+
list_for_each_entry_safe(publ, safe, &info->zone_list, zone_list) {
962+
tipc_nametbl_remove_publ(publ->type, publ->lower, publ->node,
963+
publ->ref, publ->key);
964+
}
965+
}
966+
944967
void tipc_nametbl_stop(void)
945968
{
946969
u32 i;
970+
struct name_seq *seq;
971+
struct hlist_head *seq_head;
972+
struct hlist_node *safe;
947973

948-
/* Verify name table is empty, then release it */
974+
/* Verify name table is empty and purge any lingering
975+
* publications, then release the name table
976+
*/
949977
write_lock_bh(&tipc_nametbl_lock);
950978
for (i = 0; i < TIPC_NAMETBL_SIZE; i++) {
951979
if (hlist_empty(&table.types[i]))
952980
continue;
953-
pr_err("nametbl_stop(): orphaned hash chain detected\n");
954-
break;
981+
seq_head = &table.types[i];
982+
hlist_for_each_entry_safe(seq, safe, seq_head, ns_list) {
983+
tipc_purge_publications(seq);
984+
}
985+
continue;
955986
}
956987
kfree(table.types);
957988
table.types = NULL;

net/tipc/server.c

+7-7
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,13 @@ static void tipc_clean_outqueues(struct tipc_conn *con);
8787
static void tipc_conn_kref_release(struct kref *kref)
8888
{
8989
struct tipc_conn *con = container_of(kref, struct tipc_conn, kref);
90-
struct tipc_server *s = con->server;
9190

9291
if (con->sock) {
9392
tipc_sock_release_local(con->sock);
9493
con->sock = NULL;
9594
}
9695

9796
tipc_clean_outqueues(con);
98-
99-
if (con->conid)
100-
s->tipc_conn_shutdown(con->conid, con->usr_data);
101-
10297
kfree(con);
10398
}
10499

@@ -181,6 +176,9 @@ static void tipc_close_conn(struct tipc_conn *con)
181176
struct tipc_server *s = con->server;
182177

183178
if (test_and_clear_bit(CF_CONNECTED, &con->flags)) {
179+
if (con->conid)
180+
s->tipc_conn_shutdown(con->conid, con->usr_data);
181+
184182
spin_lock_bh(&s->idr_lock);
185183
idr_remove(&s->conn_idr, con->conid);
186184
s->idr_in_use--;
@@ -429,10 +427,12 @@ int tipc_conn_sendmsg(struct tipc_server *s, int conid,
429427
list_add_tail(&e->list, &con->outqueue);
430428
spin_unlock_bh(&con->outqueue_lock);
431429

432-
if (test_bit(CF_CONNECTED, &con->flags))
430+
if (test_bit(CF_CONNECTED, &con->flags)) {
433431
if (!queue_work(s->send_wq, &con->swork))
434432
conn_put(con);
435-
433+
} else {
434+
conn_put(con);
435+
}
436436
return 0;
437437
}
438438

net/tipc/socket.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -997,7 +997,7 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long timeo)
997997

998998
for (;;) {
999999
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1000-
if (skb_queue_empty(&sk->sk_receive_queue)) {
1000+
if (timeo && skb_queue_empty(&sk->sk_receive_queue)) {
10011001
if (sock->state == SS_DISCONNECTING) {
10021002
err = -ENOTCONN;
10031003
break;
@@ -1623,7 +1623,7 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo)
16231623
for (;;) {
16241624
prepare_to_wait_exclusive(sk_sleep(sk), &wait,
16251625
TASK_INTERRUPTIBLE);
1626-
if (skb_queue_empty(&sk->sk_receive_queue)) {
1626+
if (timeo && skb_queue_empty(&sk->sk_receive_queue)) {
16271627
release_sock(sk);
16281628
timeo = schedule_timeout(timeo);
16291629
lock_sock(sk);

net/tipc/subscr.c

+2-17
Original file line numberDiff line numberDiff line change
@@ -96,20 +96,16 @@ static void subscr_send_event(struct tipc_subscription *sub, u32 found_lower,
9696
{
9797
struct tipc_subscriber *subscriber = sub->subscriber;
9898
struct kvec msg_sect;
99-
int ret;
10099

101100
msg_sect.iov_base = (void *)&sub->evt;
102101
msg_sect.iov_len = sizeof(struct tipc_event);
103-
104102
sub->evt.event = htohl(event, sub->swap);
105103
sub->evt.found_lower = htohl(found_lower, sub->swap);
106104
sub->evt.found_upper = htohl(found_upper, sub->swap);
107105
sub->evt.port.ref = htohl(port_ref, sub->swap);
108106
sub->evt.port.node = htohl(node, sub->swap);
109-
ret = tipc_conn_sendmsg(&topsrv, subscriber->conid, NULL,
110-
msg_sect.iov_base, msg_sect.iov_len);
111-
if (ret < 0)
112-
pr_err("Sending subscription event failed, no memory\n");
107+
tipc_conn_sendmsg(&topsrv, subscriber->conid, NULL, msg_sect.iov_base,
108+
msg_sect.iov_len);
113109
}
114110

115111
/**
@@ -153,14 +149,6 @@ static void subscr_timeout(struct tipc_subscription *sub)
153149
/* The spin lock per subscriber is used to protect its members */
154150
spin_lock_bh(&subscriber->lock);
155151

156-
/* Validate if the connection related to the subscriber is
157-
* closed (in case subscriber is terminating)
158-
*/
159-
if (subscriber->conid == 0) {
160-
spin_unlock_bh(&subscriber->lock);
161-
return;
162-
}
163-
164152
/* Validate timeout (in case subscription is being cancelled) */
165153
if (sub->timeout == TIPC_WAIT_FOREVER) {
166154
spin_unlock_bh(&subscriber->lock);
@@ -215,9 +203,6 @@ static void subscr_release(struct tipc_subscriber *subscriber)
215203

216204
spin_lock_bh(&subscriber->lock);
217205

218-
/* Invalidate subscriber reference */
219-
subscriber->conid = 0;
220-
221206
/* Destroy any existing subscriptions for subscriber */
222207
list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list,
223208
subscription_list) {

0 commit comments

Comments
 (0)