2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2011 Daniel Borkmann.
5 * Subject to the GPL, version 2.
19 /* Flow to CPU mapper / scheduler to keep connection CPU-local */
23 struct map_entry
*next
;
26 static struct hash_table mapper
;
28 static unsigned int *cpu_assigned
= NULL
;
30 static unsigned int cpu_len
= 0;
32 static struct rwlock map_lock
;
34 void init_cpusched(unsigned int cpus
)
36 rwlock_init(&map_lock
);
37 rwlock_wr_lock(&map_lock
);
39 cpu_assigned
= xzmalloc(cpus
* sizeof(*cpu_assigned
));
40 memset(&mapper
, 0, sizeof(mapper
));
42 rwlock_unlock(&map_lock
);
45 static int get_appropriate_cpu(void)
49 for (i
= 0; i
< cpu_len
; ++i
) {
50 if (cpu_assigned
[i
] < work
) {
51 work
= cpu_assigned
[i
];
58 unsigned int socket_to_cpu(int fd
)
61 struct map_entry
*entry
;
64 rwlock_rd_lock(&map_lock
);
65 entry
= lookup_hash(fd
, &mapper
);
66 while (entry
&& fd
!= entry
->fd
)
68 if (entry
&& fd
== entry
->fd
)
72 rwlock_unlock(&map_lock
);
77 unsigned int register_socket(int fd
)
80 struct map_entry
*entry
;
82 rwlock_wr_lock(&map_lock
);
83 entry
= xzmalloc(sizeof(*entry
));
85 entry
->cpu
= get_appropriate_cpu();
86 cpu_assigned
[entry
->cpu
]++;
87 pos
= insert_hash(entry
->fd
, entry
, &mapper
);
92 rwlock_unlock(&map_lock
);
97 static struct map_entry
*socket_to_map_entry(int fd
)
99 struct map_entry
*entry
, *ret
= NULL
;
102 rwlock_rd_lock(&map_lock
);
103 entry
= lookup_hash(fd
, &mapper
);
104 while (entry
&& fd
!= entry
->fd
)
106 if (entry
&& fd
== entry
->fd
)
110 rwlock_unlock(&map_lock
);
115 void unregister_socket(int fd
)
117 struct map_entry
*pos
;
118 struct map_entry
*entry
= socket_to_map_entry(fd
);
120 if (!entry
== 0 && errno
== ENOENT
)
122 rwlock_wr_lock(&map_lock
);
123 cpu_assigned
[entry
->cpu
]--;
124 pos
= remove_hash(entry
->fd
, entry
, entry
->next
, &mapper
);
125 while (pos
&& pos
->next
&& pos
->next
!= entry
)
127 if (pos
&& pos
->next
&& pos
->next
== entry
)
128 pos
->next
= entry
->next
;
131 rwlock_unlock(&map_lock
);
134 static int cleanup_batch(void *ptr
)
136 struct map_entry
*next
;
137 struct map_entry
*e
= ptr
;
141 while ((next
= e
->next
)) {
150 void destroy_cpusched(void)
152 rwlock_wr_lock(&map_lock
);
155 for_each_hash(&mapper
, cleanup_batch
);
157 rwlock_unlock(&map_lock
);
158 rwlock_destroy(&map_lock
);