aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/subscr.h
diff options
context:
space:
mode:
authorJon Maloy <jon.maloy@ericsson.com>2018-02-15 10:40:44 +0100
committerDavid S. Miller <davem@davemloft.net>2018-02-16 15:26:33 -0500
commitdf79d040dcd7d7e580c50edf40b82e677fe84801 (patch)
treef2d1629f209ee648d71ac4278ce490b0f648205f /net/tipc/subscr.h
parenttipc: remove unnecessary function pointers (diff)
downloadlinux-dev-df79d040dcd7d7e580c50edf40b82e677fe84801.tar.xz
linux-dev-df79d040dcd7d7e580c50edf40b82e677fe84801.zip
tipc: eliminate struct tipc_subscriber
It is unnecessary to keep two structures, struct tipc_conn and struct tipc_subscriber, with a one-to-one relationship and still with different life cycles. The fact that the two often run in different contexts, and still may access each other via direct pointers constitutes an additional hazard, something we have experienced at several occasions, and still see happening. We have identified at least two remaining problems that are easier to fix if we simplify the topology server data structure somewhat. - When there is a race between a subscription up/down event and a timeout event, it is fully possible that the former might be delivered after the latter, leading to confusion for the receiver. - The function tipc_subcrp_timeout() is executing in interrupt context, while the following call chain is at least theoretically possible: tipc_subscrp_timeout() tipc_subscrp_send_event() tipc_conn_sendmsg() conn_put() tipc_conn_kref_release() sock_release(sock) I.e., we end up calling a function that might try to sleep in interrupt context. To eliminate this, we need to ensure that the tipc_conn structure and the socket, as well as the subscription instances, only are deleted in work queue context, i.e., after the timeout event really has been sent out. We now remove this unnecessary complexity, by merging data and functionality of the subscriber structure into struct tipc_conn and the associated file server.c. We thereafter add a spinlock and a new 'inactive' state to the subscription structure. Using those, both problems described above can be easily solved. Acked-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/subscr.h')
-rw-r--r--net/tipc/subscr.h17
1 files changed, 10 insertions, 7 deletions
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h
index a736f29ba9ab..cfd0cb3a1da8 100644
--- a/net/tipc/subscr.h
+++ b/net/tipc/subscr.h
@@ -43,7 +43,7 @@
#define TIPC_MAX_PUBLICATIONS 65535
struct tipc_subscription;
-struct tipc_subscriber;
+struct tipc_conn;
/**
* struct tipc_subscription - TIPC network topology subscription object
@@ -58,19 +58,22 @@ struct tipc_subscriber;
*/
struct tipc_subscription {
struct kref kref;
- struct tipc_subscriber *subscriber;
struct net *net;
struct timer_list timer;
struct list_head nameseq_list;
struct list_head subscrp_list;
- int swap;
struct tipc_event evt;
+ int conid;
+ bool swap;
+ bool inactive;
+ spinlock_t lock; /* serialize up/down and timer events */
};
-struct tipc_subscriber *tipc_subscrb_create(int conid);
-void tipc_subscrb_delete(struct tipc_subscriber *subscriber);
-int tipc_subscrb_rcv(struct net *net, int conid, void *usr_data,
- void *buf, size_t len);
+struct tipc_subscription *tipc_subscrp_subscribe(struct net *net,
+ struct tipc_subscr *s,
+ int conid, bool swap,
+ bool status);
+void tipc_sub_delete(struct tipc_subscription *sub);
int tipc_subscrp_check_overlap(struct tipc_name_seq *seq, u32 found_lower,
u32 found_upper);
void tipc_subscrp_report_overlap(struct tipc_subscription *sub,