#include <linux/sched/mm.h>
#include <linux/jiffies.h>
#include <linux/slab.h>
-#include <linux/idr.h>
+#include <linux/xarray.h>
#include <linux/kref.h>
#include <linux/net.h>
#include <linux/export.h>
{
int ret;
- spin_lock(&nn->nn_lock);
- ret = idr_alloc(&nn->nn_status_idr, nsw, 0, 0, GFP_ATOMIC);
- if (ret >= 0) {
- nsw->ns_id = ret;
- list_add_tail(&nsw->ns_node_item, &nn->nn_status_list);
- }
- spin_unlock(&nn->nn_lock);
+ ret = xa_alloc(&nn->nn_statuses, &nsw->ns_id, nsw, xa_limit_31b,
+ GFP_ATOMIC);
if (ret < 0)
return ret;
{
assert_spin_locked(&nn->nn_lock);
- if (!list_empty(&nsw->ns_node_item)) {
- list_del_init(&nsw->ns_node_item);
+ if (nsw->ns_id != -1) {
nsw->ns_sys_status = sys_status;
nsw->ns_status = status;
- idr_remove(&nn->nn_status_idr, nsw->ns_id);
+ xa_erase(&nn->nn_statuses, nsw->ns_id);
+ nsw->ns_id = -1;
wake_up(&nsw->ns_wq);
}
}
s32 status)
{
spin_lock(&nn->nn_lock);
- if (nsw == NULL) {
- if (id > INT_MAX)
- goto out;
-
- nsw = idr_find(&nn->nn_status_idr, id);
- if (nsw == NULL)
- goto out;
- }
-
- o2net_complete_nsw_locked(nn, nsw, sys_status, status);
-
-out:
+ if (nsw == NULL)
+ nsw = xa_load(&nn->nn_statuses, id);
+ if (nsw != NULL)
+ o2net_complete_nsw_locked(nn, nsw, sys_status, status);
spin_unlock(&nn->nn_lock);
return;
}
static void o2net_complete_nodes_nsw(struct o2net_node *nn)
{
- struct o2net_status_wait *nsw, *tmp;
+ struct o2net_status_wait *nsw;
+ unsigned long index;
unsigned int num_kills = 0;
assert_spin_locked(&nn->nn_lock);
- list_for_each_entry_safe(nsw, tmp, &nn->nn_status_list, ns_node_item) {
+ xa_for_each(&nn->nn_statuses, index, nsw) {
o2net_complete_nsw_locked(nn, nsw, O2NET_ERR_DIED, 0);
num_kills++;
}
{
int completed;
spin_lock(&nn->nn_lock);
- completed = list_empty(&nsw->ns_node_item);
+ completed = (nsw->ns_id == -1);
spin_unlock(&nn->nn_lock);
return completed;
}
struct kvec *vec = NULL;
struct o2net_sock_container *sc = NULL;
struct o2net_node *nn = o2net_nn_from_num(target_node);
- struct o2net_status_wait nsw = {
- .ns_node_item = LIST_HEAD_INIT(nsw.ns_node_item),
- };
+ struct o2net_status_wait nsw = { };
struct o2net_send_tracking nst;
o2net_init_nst(&nst, msg_type, key, current, target_node);
/* until we see hb from a node we'll return einval */
nn->nn_persistent_error = -ENOTCONN;
init_waitqueue_head(&nn->nn_sc_wq);
- idr_init(&nn->nn_status_idr);
- INIT_LIST_HEAD(&nn->nn_status_list);
+ xa_init_flags(&nn->nn_statuses, XA_FLAGS_ALLOC);
}
return 0;