Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
This commit is contained in:
@@ -51,12 +51,12 @@ const char tipc_bclink_name[] = "broadcast-link";
|
||||
* struct tipc_bc_base - base structure for keeping broadcast send state
|
||||
* @link: broadcast send link structure
|
||||
* @inputq: data input queue; will only carry SOCK_WAKEUP messages
|
||||
* @dest: array keeping number of reachable destinations per bearer
|
||||
* @dests: array keeping number of reachable destinations per bearer
|
||||
* @primary_bearer: a bearer having links to all broadcast destinations, if any
|
||||
* @bcast_support: indicates if primary bearer, if any, supports broadcast
|
||||
* @rcast_support: indicates if all peer nodes support replicast
|
||||
* @rc_ratio: dest count as percentage of cluster size where send method changes
|
||||
* @bc_threshold: calculated drom rc_ratio; if dests > threshold use broadcast
|
||||
* @bc_threshold: calculated from rc_ratio; if dests > threshold use broadcast
|
||||
*/
|
||||
struct tipc_bc_base {
|
||||
struct tipc_link *link;
|
||||
|
@@ -84,7 +84,9 @@ static int tipc_sock_diag_handler_dump(struct sk_buff *skb,
|
||||
|
||||
if (h->nlmsg_flags & NLM_F_DUMP) {
|
||||
struct netlink_dump_control c = {
|
||||
.start = tipc_dump_start,
|
||||
.dump = tipc_diag_dump,
|
||||
.done = tipc_dump_done,
|
||||
};
|
||||
netlink_dump_start(net->diag_nlsk, skb, h, &c);
|
||||
return 0;
|
||||
|
@@ -980,20 +980,17 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
|
||||
struct tipc_dest *tipc_dest_find(struct list_head *l, u32 node, u32 port)
|
||||
{
|
||||
u64 value = (u64)node << 32 | port;
|
||||
struct tipc_dest *dst;
|
||||
|
||||
list_for_each_entry(dst, l, list) {
|
||||
if (dst->value != value)
|
||||
continue;
|
||||
return dst;
|
||||
if (dst->node == node && dst->port == port)
|
||||
return dst;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool tipc_dest_push(struct list_head *l, u32 node, u32 port)
|
||||
{
|
||||
u64 value = (u64)node << 32 | port;
|
||||
struct tipc_dest *dst;
|
||||
|
||||
if (tipc_dest_find(l, node, port))
|
||||
@@ -1002,7 +999,8 @@ bool tipc_dest_push(struct list_head *l, u32 node, u32 port)
|
||||
dst = kmalloc(sizeof(*dst), GFP_ATOMIC);
|
||||
if (unlikely(!dst))
|
||||
return false;
|
||||
dst->value = value;
|
||||
dst->node = node;
|
||||
dst->port = port;
|
||||
list_add(&dst->list, l);
|
||||
return true;
|
||||
}
|
||||
|
@@ -133,13 +133,8 @@ void tipc_nametbl_stop(struct net *net);
|
||||
|
||||
struct tipc_dest {
|
||||
struct list_head list;
|
||||
union {
|
||||
struct {
|
||||
u32 port;
|
||||
u32 node;
|
||||
};
|
||||
u64 value;
|
||||
};
|
||||
u32 port;
|
||||
u32 node;
|
||||
};
|
||||
|
||||
struct tipc_dest *tipc_dest_find(struct list_head *l, u32 node, u32 port);
|
||||
|
@@ -167,7 +167,9 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
|
||||
},
|
||||
{
|
||||
.cmd = TIPC_NL_SOCK_GET,
|
||||
.start = tipc_dump_start,
|
||||
.dumpit = tipc_nl_sk_dump,
|
||||
.done = tipc_dump_done,
|
||||
.policy = tipc_nl_policy,
|
||||
},
|
||||
{
|
||||
|
@@ -2672,6 +2672,8 @@ void tipc_sk_reinit(struct net *net)
|
||||
|
||||
rhashtable_walk_stop(&iter);
|
||||
} while (tsk == ERR_PTR(-EAGAIN));
|
||||
|
||||
rhashtable_walk_exit(&iter);
|
||||
}
|
||||
|
||||
static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid)
|
||||
@@ -3227,45 +3229,69 @@ int tipc_nl_sk_walk(struct sk_buff *skb, struct netlink_callback *cb,
|
||||
struct netlink_callback *cb,
|
||||
struct tipc_sock *tsk))
|
||||
{
|
||||
struct net *net = sock_net(skb->sk);
|
||||
struct tipc_net *tn = tipc_net(net);
|
||||
const struct bucket_table *tbl;
|
||||
u32 prev_portid = cb->args[1];
|
||||
u32 tbl_id = cb->args[0];
|
||||
struct rhash_head *pos;
|
||||
struct rhashtable_iter *iter = (void *)cb->args[0];
|
||||
struct tipc_sock *tsk;
|
||||
int err;
|
||||
|
||||
rcu_read_lock();
|
||||
tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht);
|
||||
for (; tbl_id < tbl->size; tbl_id++) {
|
||||
rht_for_each_entry_rcu(tsk, pos, tbl, tbl_id, node) {
|
||||
spin_lock_bh(&tsk->sk.sk_lock.slock);
|
||||
if (prev_portid && prev_portid != tsk->portid) {
|
||||
spin_unlock_bh(&tsk->sk.sk_lock.slock);
|
||||
rhashtable_walk_start(iter);
|
||||
while ((tsk = rhashtable_walk_next(iter)) != NULL) {
|
||||
if (IS_ERR(tsk)) {
|
||||
err = PTR_ERR(tsk);
|
||||
if (err == -EAGAIN) {
|
||||
err = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
err = skb_handler(skb, cb, tsk);
|
||||
if (err) {
|
||||
prev_portid = tsk->portid;
|
||||
spin_unlock_bh(&tsk->sk.sk_lock.slock);
|
||||
goto out;
|
||||
}
|
||||
|
||||
prev_portid = 0;
|
||||
spin_unlock_bh(&tsk->sk.sk_lock.slock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
cb->args[0] = tbl_id;
|
||||
cb->args[1] = prev_portid;
|
||||
|
||||
sock_hold(&tsk->sk);
|
||||
rhashtable_walk_stop(iter);
|
||||
lock_sock(&tsk->sk);
|
||||
err = skb_handler(skb, cb, tsk);
|
||||
if (err) {
|
||||
release_sock(&tsk->sk);
|
||||
sock_put(&tsk->sk);
|
||||
goto out;
|
||||
}
|
||||
release_sock(&tsk->sk);
|
||||
rhashtable_walk_start(iter);
|
||||
sock_put(&tsk->sk);
|
||||
}
|
||||
rhashtable_walk_stop(iter);
|
||||
out:
|
||||
return skb->len;
|
||||
}
|
||||
EXPORT_SYMBOL(tipc_nl_sk_walk);
|
||||
|
||||
int tipc_dump_start(struct netlink_callback *cb)
|
||||
{
|
||||
struct rhashtable_iter *iter = (void *)cb->args[0];
|
||||
struct net *net = sock_net(cb->skb->sk);
|
||||
struct tipc_net *tn = tipc_net(net);
|
||||
|
||||
if (!iter) {
|
||||
iter = kmalloc(sizeof(*iter), GFP_KERNEL);
|
||||
if (!iter)
|
||||
return -ENOMEM;
|
||||
|
||||
cb->args[0] = (long)iter;
|
||||
}
|
||||
|
||||
rhashtable_walk_enter(&tn->sk_rht, iter);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(tipc_dump_start);
|
||||
|
||||
int tipc_dump_done(struct netlink_callback *cb)
|
||||
{
|
||||
struct rhashtable_iter *hti = (void *)cb->args[0];
|
||||
|
||||
rhashtable_walk_exit(hti);
|
||||
kfree(hti);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(tipc_dump_done);
|
||||
|
||||
int tipc_sk_fill_sock_diag(struct sk_buff *skb, struct netlink_callback *cb,
|
||||
struct tipc_sock *tsk, u32 sk_filter_state,
|
||||
u64 (*tipc_diag_gen_cookie)(struct sock *sk))
|
||||
|
@@ -68,4 +68,6 @@ int tipc_nl_sk_walk(struct sk_buff *skb, struct netlink_callback *cb,
|
||||
int (*skb_handler)(struct sk_buff *skb,
|
||||
struct netlink_callback *cb,
|
||||
struct tipc_sock *tsk));
|
||||
int tipc_dump_start(struct netlink_callback *cb);
|
||||
int tipc_dump_done(struct netlink_callback *cb);
|
||||
#endif
|
||||
|
@@ -307,8 +307,8 @@ static void tipc_conn_send_work(struct work_struct *work)
|
||||
conn_put(con);
|
||||
}
|
||||
|
||||
/* tipc_conn_queue_evt() - interrupt level call from a subscription instance
|
||||
* The queued work is launched into tipc_send_work()->tipc_send_to_sock()
|
||||
/* tipc_topsrv_queue_evt() - interrupt level call from a subscription instance
|
||||
* The queued work is launched into tipc_conn_send_work()->tipc_conn_send_to_sock()
|
||||
*/
|
||||
void tipc_topsrv_queue_evt(struct net *net, int conid,
|
||||
u32 event, struct tipc_event *evt)
|
||||
|
Reference in New Issue
Block a user