diff options
| author | Herbert Xu <herbert@gondor.apana.org.au> | 2013-09-07 12:53:35 +1000 | 
|---|---|---|
| committer | Herbert Xu <herbert@gondor.apana.org.au> | 2013-09-07 12:53:35 +1000 | 
| commit | eeca9fad52fc4bfdf42c38bfcf383e932eb3e9d6 (patch) | |
| tree | cc51c880459d41c0e8d7576405bef4c987bc7aa0 /net/tipc/port.c | |
| parent | ff6f83fc9d44db09997937c3475d525a6866fbb4 (diff) | |
| parent | b48a97be8e6c2afdba2f3b61fd88c3c7743fbd73 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux
Merge upstream tree in order to reinstate crct10dif.
Diffstat (limited to 'net/tipc/port.c')
| -rw-r--r-- | net/tipc/port.c | 320 | 
1 files changed, 11 insertions, 309 deletions
diff --git a/net/tipc/port.c b/net/tipc/port.c index 18098cac62f..b3ed2fcab4f 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -2,7 +2,7 @@   * net/tipc/port.c: TIPC port code   *   * Copyright (c) 1992-2007, Ericsson AB - * Copyright (c) 2004-2008, 2010-2011, Wind River Systems + * Copyright (c) 2004-2008, 2010-2013, Wind River Systems   * All rights reserved.   *   * Redistribution and use in source and binary forms, with or without @@ -46,11 +46,7 @@  #define MAX_REJECT_SIZE 1024 -static struct sk_buff *msg_queue_head; -static struct sk_buff *msg_queue_tail; -  DEFINE_SPINLOCK(tipc_port_list_lock); -static DEFINE_SPINLOCK(queue_lock);  static LIST_HEAD(ports);  static void port_handle_node_down(unsigned long ref); @@ -119,7 +115,7 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,  	msg_set_nameupper(hdr, seq->upper);  	msg_set_hdr_sz(hdr, MCAST_H_SIZE);  	res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE, -			!oport->user_port, &buf); +			     &buf);  	if (unlikely(!buf))  		return res; @@ -206,14 +202,15 @@ exit:  }  /** - * tipc_createport_raw - create a generic TIPC port + * tipc_createport - create a generic TIPC port   *   * Returns pointer to (locked) TIPC port, or NULL if unable to create it   */ -struct tipc_port *tipc_createport_raw(void *usr_handle, -			u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), -			void (*wakeup)(struct tipc_port *), -			const u32 importance) +struct tipc_port *tipc_createport(struct sock *sk, +				  u32 (*dispatcher)(struct tipc_port *, +				  struct sk_buff *), +				  void (*wakeup)(struct tipc_port *), +				  const u32 importance)  {  	struct tipc_port *p_ptr;  	struct tipc_msg *msg; @@ -231,14 +228,13 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,  		return NULL;  	} -	p_ptr->usr_handle = usr_handle; +	p_ptr->sk = sk;  	p_ptr->max_pkt = MAX_PKT_DEFAULT;  	p_ptr->ref = ref;  	INIT_LIST_HEAD(&p_ptr->wait_list);  	INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);  	p_ptr->dispatcher = dispatcher;  	p_ptr->wakeup = wakeup; -	p_ptr->user_port = NULL;  	k_init_timer(&p_ptr->timer, (Handler)port_timeout, ref);  	INIT_LIST_HEAD(&p_ptr->publications);  	INIT_LIST_HEAD(&p_ptr->port_list); @@ -275,7 +271,6 @@ int tipc_deleteport(u32 ref)  		buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT);  		tipc_nodesub_unsubscribe(&p_ptr->subscription);  	} -	kfree(p_ptr->user_port);  	spin_lock_bh(&tipc_port_list_lock);  	list_del(&p_ptr->port_list); @@ -448,7 +443,7 @@ int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,  	int res;  	res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE, -			!p_ptr->user_port, &buf); +			     &buf);  	if (!buf)  		return res; @@ -668,215 +663,6 @@ void tipc_port_reinit(void)  	spin_unlock_bh(&tipc_port_list_lock);  } - -/* - *  port_dispatcher_sigh(): Signal handler for messages destinated - *                          to the tipc_port interface. - */ -static void port_dispatcher_sigh(void *dummy) -{ -	struct sk_buff *buf; - -	spin_lock_bh(&queue_lock); -	buf = msg_queue_head; -	msg_queue_head = NULL; -	spin_unlock_bh(&queue_lock); - -	while (buf) { -		struct tipc_port *p_ptr; -		struct user_port *up_ptr; -		struct tipc_portid orig; -		struct tipc_name_seq dseq; -		void *usr_handle; -		int connected; -		int peer_invalid; -		int published; -		u32 message_type; - -		struct sk_buff *next = buf->next; -		struct tipc_msg *msg = buf_msg(buf); -		u32 dref = msg_destport(msg); - -		message_type = msg_type(msg); -		if (message_type > TIPC_DIRECT_MSG) -			goto reject;	/* Unsupported message type */ - -		p_ptr = tipc_port_lock(dref); -		if (!p_ptr) -			goto reject;	/* Port deleted while msg in queue */ - -		orig.ref = msg_origport(msg); -		orig.node = msg_orignode(msg); -		up_ptr = p_ptr->user_port; -		usr_handle = up_ptr->usr_handle; -		connected = p_ptr->connected; -		peer_invalid = connected && !tipc_port_peer_msg(p_ptr, msg); -		published = p_ptr->published; - -		if (unlikely(msg_errcode(msg))) -			goto err; - -		switch (message_type) { - -		case TIPC_CONN_MSG:{ -				tipc_conn_msg_event cb = up_ptr->conn_msg_cb; -				u32 dsz; - -				tipc_port_unlock(p_ptr); -				if (unlikely(!cb)) -					goto reject; -				if (unlikely(!connected)) { -					if (tipc_connect(dref, &orig)) -						goto reject; -				} else if (peer_invalid) -					goto reject; -				dsz = msg_data_sz(msg); -				if (unlikely(dsz && -					     (++p_ptr->conn_unacked >= -					      TIPC_FLOW_CONTROL_WIN))) -					tipc_acknowledge(dref, -							 p_ptr->conn_unacked); -				skb_pull(buf, msg_hdr_sz(msg)); -				cb(usr_handle, dref, &buf, msg_data(msg), dsz); -				break; -			} -		case TIPC_DIRECT_MSG:{ -				tipc_msg_event cb = up_ptr->msg_cb; - -				tipc_port_unlock(p_ptr); -				if (unlikely(!cb || connected)) -					goto reject; -				skb_pull(buf, msg_hdr_sz(msg)); -				cb(usr_handle, dref, &buf, msg_data(msg), -				   msg_data_sz(msg), msg_importance(msg), -				   &orig); -				break; -			} -		case TIPC_MCAST_MSG: -		case TIPC_NAMED_MSG:{ -				tipc_named_msg_event cb = up_ptr->named_msg_cb; - -				tipc_port_unlock(p_ptr); -				if (unlikely(!cb || connected || !published)) -					goto reject; -				dseq.type =  msg_nametype(msg); -				dseq.lower = msg_nameinst(msg); -				dseq.upper = (message_type == TIPC_NAMED_MSG) -					? dseq.lower : msg_nameupper(msg); -				skb_pull(buf, msg_hdr_sz(msg)); -				cb(usr_handle, dref, &buf, msg_data(msg), -				   msg_data_sz(msg), msg_importance(msg), -				   &orig, &dseq); -				break; -			} -		} -		if (buf) -			kfree_skb(buf); -		buf = next; -		continue; -err: -		switch (message_type) { - -		case TIPC_CONN_MSG:{ -				tipc_conn_shutdown_event cb = -					up_ptr->conn_err_cb; - -				tipc_port_unlock(p_ptr); -				if (!cb || !connected || peer_invalid) -					break; -				tipc_disconnect(dref); -				skb_pull(buf, msg_hdr_sz(msg)); -				cb(usr_handle, dref, &buf, msg_data(msg), -				   msg_data_sz(msg), msg_errcode(msg)); -				break; -			} -		case TIPC_DIRECT_MSG:{ -				tipc_msg_err_event cb = up_ptr->err_cb; - -				tipc_port_unlock(p_ptr); -				if (!cb || connected) -					break; -				skb_pull(buf, msg_hdr_sz(msg)); -				cb(usr_handle, dref, &buf, msg_data(msg), -				   msg_data_sz(msg), msg_errcode(msg), &orig); -				break; -			} -		case TIPC_MCAST_MSG: -		case TIPC_NAMED_MSG:{ -				tipc_named_msg_err_event cb = -					up_ptr->named_err_cb; - -				tipc_port_unlock(p_ptr); -				if (!cb || connected) -					break; -				dseq.type =  msg_nametype(msg); -				dseq.lower = msg_nameinst(msg); -				dseq.upper = (message_type == TIPC_NAMED_MSG) -					? dseq.lower : msg_nameupper(msg); -				skb_pull(buf, msg_hdr_sz(msg)); -				cb(usr_handle, dref, &buf, msg_data(msg), -				   msg_data_sz(msg), msg_errcode(msg), &dseq); -				break; -			} -		} -		if (buf) -			kfree_skb(buf); -		buf = next; -		continue; -reject: -		tipc_reject_msg(buf, TIPC_ERR_NO_PORT); -		buf = next; -	} -} - -/* - *  port_dispatcher(): Dispatcher for messages destinated - *  to the tipc_port interface. Called with port locked. - */ -static u32 port_dispatcher(struct tipc_port *dummy, struct sk_buff *buf) -{ -	buf->next = NULL; -	spin_lock_bh(&queue_lock); -	if (msg_queue_head) { -		msg_queue_tail->next = buf; -		msg_queue_tail = buf; -	} else { -		msg_queue_tail = msg_queue_head = buf; -		tipc_k_signal((Handler)port_dispatcher_sigh, 0); -	} -	spin_unlock_bh(&queue_lock); -	return 0; -} - -/* - * Wake up port after congestion: Called with port locked - */ -static void port_wakeup_sh(unsigned long ref) -{ -	struct tipc_port *p_ptr; -	struct user_port *up_ptr; -	tipc_continue_event cb = NULL; -	void *uh = NULL; - -	p_ptr = tipc_port_lock(ref); -	if (p_ptr) { -		up_ptr = p_ptr->user_port; -		if (up_ptr) { -			cb = up_ptr->continue_event_cb; -			uh = up_ptr->usr_handle; -		} -		tipc_port_unlock(p_ptr); -	} -	if (cb) -		cb(uh, ref); -} - - -static void port_wakeup(struct tipc_port *p_ptr) -{ -	tipc_k_signal((Handler)port_wakeup_sh, p_ptr->ref); -} -  void tipc_acknowledge(u32 ref, u32 ack)  {  	struct tipc_port *p_ptr; @@ -893,50 +679,6 @@ void tipc_acknowledge(u32 ref, u32 ack)  	tipc_net_route_msg(buf);  } -/* - * tipc_createport(): user level call. - */ -int tipc_createport(void *usr_handle, -		    unsigned int importance, -		    tipc_msg_err_event error_cb, -		    tipc_named_msg_err_event named_error_cb, -		    tipc_conn_shutdown_event conn_error_cb, -		    tipc_msg_event msg_cb, -		    tipc_named_msg_event named_msg_cb, -		    tipc_conn_msg_event conn_msg_cb, -		    tipc_continue_event continue_event_cb, /* May be zero */ -		    u32 *portref) -{ -	struct user_port *up_ptr; -	struct tipc_port *p_ptr; - -	up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); -	if (!up_ptr) { -		pr_warn("Port creation failed, no memory\n"); -		return -ENOMEM; -	} -	p_ptr = tipc_createport_raw(NULL, port_dispatcher, port_wakeup, -				    importance); -	if (!p_ptr) { -		kfree(up_ptr); -		return -ENOMEM; -	} - -	p_ptr->user_port = up_ptr; -	up_ptr->usr_handle = usr_handle; -	up_ptr->ref = p_ptr->ref; -	up_ptr->err_cb = error_cb; -	up_ptr->named_err_cb = named_error_cb; -	up_ptr->conn_err_cb = conn_error_cb; -	up_ptr->msg_cb = msg_cb; -	up_ptr->named_msg_cb = named_msg_cb; -	up_ptr->conn_msg_cb = conn_msg_cb; -	up_ptr->continue_event_cb = continue_event_cb; -	*portref = p_ptr->ref; -	tipc_port_unlock(p_ptr); -	return 0; -} -  int tipc_portimportance(u32 ref, unsigned int *importance)  {  	struct tipc_port *p_ptr; @@ -1184,7 +926,7 @@ static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_se  	int res;  	res = tipc_msg_build(&sender->phdr, msg_sect, num_sect, total_len, -			MAX_MSG_SIZE, !sender->user_port, &buf); +			     MAX_MSG_SIZE, &buf);  	if (likely(buf))  		tipc_port_recv_msg(buf);  	return res; @@ -1322,43 +1064,3 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest,  	}  	return -ELINKCONG;  } - -/** - * tipc_send_buf2port - send message buffer to port identity - */ -int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest, -	       struct sk_buff *buf, unsigned int dsz) -{ -	struct tipc_port *p_ptr; -	struct tipc_msg *msg; -	int res; - -	p_ptr = (struct tipc_port *)tipc_ref_deref(ref); -	if (!p_ptr || p_ptr->connected) -		return -EINVAL; - -	msg = &p_ptr->phdr; -	msg_set_type(msg, TIPC_DIRECT_MSG); -	msg_set_destnode(msg, dest->node); -	msg_set_destport(msg, dest->ref); -	msg_set_hdr_sz(msg, BASIC_H_SIZE); -	msg_set_size(msg, BASIC_H_SIZE + dsz); -	if (skb_cow(buf, BASIC_H_SIZE)) -		return -ENOMEM; - -	skb_push(buf, BASIC_H_SIZE); -	skb_copy_to_linear_data(buf, msg, BASIC_H_SIZE); - -	if (in_own_node(dest->node)) -		res = tipc_port_recv_msg(buf); -	else -		res = tipc_send_buf_fast(buf, dest->node); -	if (likely(res != -ELINKCONG)) { -		if (res > 0) -			p_ptr->sent++; -		return res; -	} -	if (port_unreliable(p_ptr)) -		return dsz; -	return -ELINKCONG; -}  | 
