⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bearer.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
}void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest){	tipc_nmap_remove(&b_ptr->nodes, dest);	tipc_disc_update_link_req(b_ptr->link_req);	tipc_bcbearer_sort();}/* * bearer_push(): Resolve bearer congestion. Force the waiting * links to push out their unsent packets, one packet per link * per iteration, until all packets are gone or congestion reoccurs. * 'tipc_net_lock' is read_locked when this function is called * bearer.lock must be taken before calling * Returns binary true(1) ore false(0) */static int bearer_push(struct bearer *b_ptr){	u32 res = TIPC_OK;	struct link *ln, *tln;	if (b_ptr->publ.blocked)		return 0;	while (!list_empty(&b_ptr->cong_links) && (res != PUSH_FAILED)) {		list_for_each_entry_safe(ln, tln, &b_ptr->cong_links, link_list) {			res = tipc_link_push_packet(ln);			if (res == PUSH_FAILED)				break;			if (res == PUSH_FINISHED)				list_move_tail(&ln->link_list, &b_ptr->links);		}	}	return list_empty(&b_ptr->cong_links);}void tipc_bearer_lock_push(struct bearer *b_ptr){	int res;	spin_lock_bh(&b_ptr->publ.lock);	res = bearer_push(b_ptr);	spin_unlock_bh(&b_ptr->publ.lock);	if (res)		tipc_bcbearer_push();}/* * Interrupt enabling new requests after bearer congestion or blocking: * See bearer_send(). */void tipc_continue(struct tipc_bearer *tb_ptr){	struct bearer *b_ptr = (struct bearer *)tb_ptr;	spin_lock_bh(&b_ptr->publ.lock);	b_ptr->continue_count++;	if (!list_empty(&b_ptr->cong_links))		tipc_k_signal((Handler)tipc_bearer_lock_push, (unsigned long)b_ptr);	b_ptr->publ.blocked = 0;	spin_unlock_bh(&b_ptr->publ.lock);}/* * Schedule link for sending of messages after the bearer * has been deblocked by 'continue()'. This method is called * when somebody tries to send a message via this link while * the bearer is congested. 'tipc_net_lock' is in read_lock here * bearer.lock is busy */static void tipc_bearer_schedule_unlocked(struct bearer *b_ptr, struct link *l_ptr){	list_move_tail(&l_ptr->link_list, &b_ptr->cong_links);}/* * Schedule link for sending of messages after the bearer * has been deblocked by 'continue()'. This method is called * when somebody tries to send a message via this link while * the bearer is congested. 'tipc_net_lock' is in read_lock here, * bearer.lock is free */void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr){	spin_lock_bh(&b_ptr->publ.lock);	tipc_bearer_schedule_unlocked(b_ptr, l_ptr);	spin_unlock_bh(&b_ptr->publ.lock);}/* * tipc_bearer_resolve_congestion(): Check if there is bearer congestion, * and if there is, try to resolve it before returning. * 'tipc_net_lock' is read_locked when this function is called */int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr){	int res = 1;	if (list_empty(&b_ptr->cong_links))		return 1;	spin_lock_bh(&b_ptr->publ.lock);	if (!bearer_push(b_ptr)) {		tipc_bearer_schedule_unlocked(b_ptr, l_ptr);		res = 0;	}	spin_unlock_bh(&b_ptr->publ.lock);	return res;}/** * tipc_enable_bearer - enable bearer with the given name */int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority){	struct bearer *b_ptr;	struct media *m_ptr;	struct bearer_name b_name;	char addr_string[16];	u32 bearer_id;	u32 with_this_prio;	u32 i;	int res = -EINVAL;	if (tipc_mode != TIPC_NET_MODE) {		warn("Bearer <%s> rejected, not supported in standalone mode\n",		     name);		return -ENOPROTOOPT;	}	if (!bearer_name_validate(name, &b_name)) {		warn("Bearer <%s> rejected, illegal name\n", name);		return -EINVAL;	}	if (!tipc_addr_domain_valid(bcast_scope) ||	    !in_scope(bcast_scope, tipc_own_addr)) {		warn("Bearer <%s> rejected, illegal broadcast scope\n", name);		return -EINVAL;	}	if ((priority < TIPC_MIN_LINK_PRI ||	     priority > TIPC_MAX_LINK_PRI) &&	    (priority != TIPC_MEDIA_LINK_PRI)) {		warn("Bearer <%s> rejected, illegal priority\n", name);		return -EINVAL;	}	write_lock_bh(&tipc_net_lock);	m_ptr = media_find(b_name.media_name);	if (!m_ptr) {		warn("Bearer <%s> rejected, media <%s> not registered\n", name,		     b_name.media_name);		goto failed;	}	if (priority == TIPC_MEDIA_LINK_PRI)		priority = m_ptr->priority;restart:	bearer_id = MAX_BEARERS;	with_this_prio = 1;	for (i = MAX_BEARERS; i-- != 0; ) {		if (!tipc_bearers[i].active) {			bearer_id = i;			continue;		}		if (!strcmp(name, tipc_bearers[i].publ.name)) {			warn("Bearer <%s> rejected, already enabled\n", name);			goto failed;		}		if ((tipc_bearers[i].priority == priority) &&		    (++with_this_prio > 2)) {			if (priority-- == 0) {				warn("Bearer <%s> rejected, duplicate priority\n",				     name);				goto failed;			}			warn("Bearer <%s> priority adjustment required %u->%u\n",			     name, priority + 1, priority);			goto restart;		}	}	if (bearer_id >= MAX_BEARERS) {		warn("Bearer <%s> rejected, bearer limit reached (%u)\n",		     name, MAX_BEARERS);		goto failed;	}	b_ptr = &tipc_bearers[bearer_id];	memset(b_ptr, 0, sizeof(struct bearer));	strcpy(b_ptr->publ.name, name);	res = m_ptr->enable_bearer(&b_ptr->publ);	if (res) {		warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res);		goto failed;	}	b_ptr->identity = bearer_id;	b_ptr->media = m_ptr;	b_ptr->net_plane = bearer_id + 'A';	b_ptr->active = 1;	b_ptr->detect_scope = bcast_scope;	b_ptr->priority = priority;	INIT_LIST_HEAD(&b_ptr->cong_links);	INIT_LIST_HEAD(&b_ptr->links);	if (m_ptr->bcast) {		b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr,							  bcast_scope, 2);	}	spin_lock_init(&b_ptr->publ.lock);	write_unlock_bh(&tipc_net_lock);	info("Enabled bearer <%s>, discovery domain %s, priority %u\n",	     name, addr_string_fill(addr_string, bcast_scope), priority);	return 0;failed:	write_unlock_bh(&tipc_net_lock);	return res;}/** * tipc_block_bearer(): Block the bearer with the given name, *                      and reset all its links */int tipc_block_bearer(const char *name){	struct bearer *b_ptr = NULL;	struct link *l_ptr;	struct link *temp_l_ptr;	read_lock_bh(&tipc_net_lock);	b_ptr = bearer_find(name);	if (!b_ptr) {		warn("Attempt to block unknown bearer <%s>\n", name);		read_unlock_bh(&tipc_net_lock);		return -EINVAL;	}	info("Blocking bearer <%s>\n", name);	spin_lock_bh(&b_ptr->publ.lock);	b_ptr->publ.blocked = 1;	list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {		struct node *n_ptr = l_ptr->owner;		spin_lock_bh(&n_ptr->lock);		tipc_link_reset(l_ptr);		spin_unlock_bh(&n_ptr->lock);	}	spin_unlock_bh(&b_ptr->publ.lock);	read_unlock_bh(&tipc_net_lock);	return TIPC_OK;}/** * bearer_disable - * * Note: This routine assumes caller holds tipc_net_lock. */static int bearer_disable(const char *name){	struct bearer *b_ptr;	struct link *l_ptr;	struct link *temp_l_ptr;	b_ptr = bearer_find(name);	if (!b_ptr) {		warn("Attempt to disable unknown bearer <%s>\n", name);		return -EINVAL;	}	info("Disabling bearer <%s>\n", name);	tipc_disc_stop_link_req(b_ptr->link_req);	spin_lock_bh(&b_ptr->publ.lock);	b_ptr->link_req = NULL;	b_ptr->publ.blocked = 1;	if (b_ptr->media->disable_bearer) {		spin_unlock_bh(&b_ptr->publ.lock);		write_unlock_bh(&tipc_net_lock);		b_ptr->media->disable_bearer(&b_ptr->publ);		write_lock_bh(&tipc_net_lock);		spin_lock_bh(&b_ptr->publ.lock);	}	list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {		tipc_link_delete(l_ptr);	}	spin_unlock_bh(&b_ptr->publ.lock);	memset(b_ptr, 0, sizeof(struct bearer));	return TIPC_OK;}int tipc_disable_bearer(const char *name){	int res;	write_lock_bh(&tipc_net_lock);	res = bearer_disable(name);	write_unlock_bh(&tipc_net_lock);	return res;}int tipc_bearer_init(void){	int res;	write_lock_bh(&tipc_net_lock);	tipc_bearers = kcalloc(MAX_BEARERS, sizeof(struct bearer), GFP_ATOMIC);	media_list = kcalloc(MAX_MEDIA, sizeof(struct media), GFP_ATOMIC);	if (tipc_bearers && media_list) {		res = TIPC_OK;	} else {		kfree(tipc_bearers);		kfree(media_list);		tipc_bearers = NULL;		media_list = NULL;		res = -ENOMEM;	}	write_unlock_bh(&tipc_net_lock);	return res;}void tipc_bearer_stop(void){	u32 i;	if (!tipc_bearers)		return;	for (i = 0; i < MAX_BEARERS; i++) {		if (tipc_bearers[i].active)			tipc_bearers[i].publ.blocked = 1;	}	for (i = 0; i < MAX_BEARERS; i++) {		if (tipc_bearers[i].active)			bearer_disable(tipc_bearers[i].publ.name);	}	kfree(tipc_bearers);	kfree(media_list);	tipc_bearers = NULL;	media_list = NULL;	media_count = 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -