33 #include <linux/slab.h>
34 #include <linux/types.h>
35 #include <linux/rbtree.h>
36 #include <linux/bitops.h>
37 #include <linux/export.h>
104 static struct rds_cong_map *rds_cong_tree_walk(
__be32 addr,
105 struct rds_cong_map *insert)
109 struct rds_cong_map *
map;
113 map =
rb_entry(parent,
struct rds_cong_map, m_rb_node);
115 if (addr < map->m_addr)
117 else if (addr > map->m_addr)
124 rb_link_node(&insert->m_rb_node, parent, p);
135 static struct rds_cong_map *rds_cong_from_addr(
__be32 addr)
137 struct rds_cong_map *
map;
138 struct rds_cong_map *
ret =
NULL;
143 map = kzalloc(
sizeof(
struct rds_cong_map),
GFP_KERNEL);
149 INIT_LIST_HEAD(&map->m_conn_list);
155 map->m_page_addrs[
i] = zp;
159 ret = rds_cong_tree_walk(addr, map);
160 spin_unlock_irqrestore(&rds_cong_lock, flags);
169 for (i = 0; i < RDS_CONG_MAP_PAGES && map->m_page_addrs[
i]; i++)
174 rdsdebug(
"map %p for addr %x\n", ret,
be32_to_cpu(addr));
187 rdsdebug(
"conn %p now on map %p\n", conn, conn->
c_lcong);
190 spin_unlock_irqrestore(&rds_cong_lock, flags);
197 rdsdebug(
"removing conn %p from map %p\n", conn, conn->
c_lcong);
200 spin_unlock_irqrestore(&rds_cong_lock, flags);
228 spin_unlock_irqrestore(&rds_cong_lock, flags);
233 rdsdebug(
"waking map %p for %pI4\n",
237 if (waitqueue_active(&map->m_waitq))
242 if (portmask && !list_empty(&rds_cong_monitor)) {
264 if (
likely(*recent == gen))
282 rdsdebug(
"setting congestion for %pI4:%u in map %p\n",
283 &map->m_addr,
ntohs(port), map);
288 __set_bit_le(off, (
void *)map->m_page_addrs[i]);
296 rdsdebug(
"clearing congestion for %pI4:%u in map %p\n",
297 &map->m_addr,
ntohs(port), map);
302 __clear_bit_le(off, (
void *)map->m_page_addrs[i]);
305 static int rds_cong_test_bit(
struct rds_cong_map *map,
__be16 port)
313 return test_bit_le(off, (
void *)map->m_page_addrs[i]);
329 struct rds_cong_map *
map;
338 spin_unlock_irqrestore(&rds_cong_lock, flags);
349 if (!rds_cong_test_bit(map, port))
359 spin_unlock_irqrestore(&rs->
rs_lock, flags);
363 if (!rds_cong_test_bit(map, port))
371 rdsdebug(
"waiting on map %p for port %u\n", map,
be16_to_cpu(port));
374 !rds_cong_test_bit(map, port));
380 struct rds_cong_map *
map;
383 while ((node =
rb_first(&rds_cong_tree))) {
384 map =
rb_entry(node,
struct rds_cong_map, m_rb_node);
385 rdsdebug(
"freeing map %p\n", map);
386 rb_erase(&map->m_rb_node, &rds_cong_tree);
387 for (i = 0; i < RDS_CONG_MAP_PAGES && map->m_page_addrs[
i]; i++)
398 struct rds_cong_map *map = conn->
c_lcong;