projects
/
userspace-rcu.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fix: call_rcu_thread() affinity failure
[userspace-rcu.git]
/
rculfhash.c
diff --git
a/rculfhash.c
b/rculfhash.c
index 2a450459f5cfa50e94bce03e00be0ad1be7b2b4f..57f1a04d46dd3d446ca88fa74267660dd7a26fe2 100644
(file)
--- a/
rculfhash.c
+++ b/
rculfhash.c
@@
-1171,11
+1171,15
@@
void partition_resize_helper(struct cds_lfht *ht, unsigned long i,
void (*fct)(struct cds_lfht *ht, unsigned long i,
unsigned long start, unsigned long len))
{
void (*fct)(struct cds_lfht *ht, unsigned long i,
unsigned long start, unsigned long len))
{
- unsigned long partition_len;
+ unsigned long partition_len
, start = 0
;
struct partition_resize_work *work;
int thread, ret;
unsigned long nr_threads;
struct partition_resize_work *work;
int thread, ret;
unsigned long nr_threads;
+ assert(nr_cpus_mask != -1);
+ if (nr_cpus_mask < 0 || len < 2 * MIN_PARTITION_PER_THREAD)
+ goto fallback;
+
/*
* Note: nr_cpus_mask + 1 is always power of 2.
* We spawn just the number of threads we need to satisfy the minimum
/*
* Note: nr_cpus_mask + 1 is always power of 2.
* We spawn just the number of threads we need to satisfy the minimum
@@
-1201,6
+1205,17
@@
void partition_resize_helper(struct cds_lfht *ht, unsigned long i,
work[thread].fct = fct;
ret = pthread_create(&(work[thread].thread_id), ht->resize_attr,
partition_resize_thread, &work[thread]);
work[thread].fct = fct;
ret = pthread_create(&(work[thread].thread_id), ht->resize_attr,
partition_resize_thread, &work[thread]);
+ if (ret == EAGAIN) {
+ /*
+ * Out of resources: wait and join the threads
+ * we've created, then handle leftovers.
+ */
+ dbg_printf("error spawning for resize, single-threading\n");
+ start = work[thread].start;
+ len -= start;
+ nr_threads = thread;
+ break;
+ }
assert(!ret);
}
for (thread = 0; thread < nr_threads; thread++) {
assert(!ret);
}
for (thread = 0; thread < nr_threads; thread++) {
@@
-1208,10
+1223,17
@@
void partition_resize_helper(struct cds_lfht *ht, unsigned long i,
assert(!ret);
}
free(work);
assert(!ret);
}
free(work);
- return;
+
+ /*
+ * A pthread_create failure above will either lead in us having
+ * no threads to join or starting at a non-zero offset,
+ * fallback to single thread processing of leftovers.
+ */
+ if (start == 0 && nr_threads > 0)
+ return;
fallback:
ht->flavor->thread_online();
fallback:
ht->flavor->thread_online();
- fct(ht, i,
0
, len);
+ fct(ht, i,
start
, len);
ht->flavor->thread_offline();
}
ht->flavor->thread_offline();
}
@@
-1250,13
+1272,6
@@
static
void init_table_populate(struct cds_lfht *ht, unsigned long i,
unsigned long len)
{
void init_table_populate(struct cds_lfht *ht, unsigned long i,
unsigned long len)
{
- assert(nr_cpus_mask != -1);
- if (nr_cpus_mask < 0 || len < 2 * MIN_PARTITION_PER_THREAD) {
- ht->flavor->thread_online();
- init_table_populate_partition(ht, i, 0, len);
- ht->flavor->thread_offline();
- return;
- }
partition_resize_helper(ht, i, len, init_table_populate_partition);
}
partition_resize_helper(ht, i, len, init_table_populate_partition);
}
@@
-1349,14
+1364,6
@@
void remove_table_partition(struct cds_lfht *ht, unsigned long i,
static
void remove_table(struct cds_lfht *ht, unsigned long i, unsigned long len)
{
static
void remove_table(struct cds_lfht *ht, unsigned long i, unsigned long len)
{
-
- assert(nr_cpus_mask != -1);
- if (nr_cpus_mask < 0 || len < 2 * MIN_PARTITION_PER_THREAD) {
- ht->flavor->thread_online();
- remove_table_partition(ht, i, 0, len);
- ht->flavor->thread_offline();
- return;
- }
partition_resize_helper(ht, i, len, remove_table_partition);
}
partition_resize_helper(ht, i, len, remove_table_partition);
}
This page took
0.023938 seconds
and
4
git commands to generate.