.. | .. |
---|
2387 | 2387 | static inline unsigned start_dir_add(struct inode *dir) |
---|
2388 | 2388 | { |
---|
2389 | 2389 | |
---|
| 2390 | + preempt_disable_rt(); |
---|
2390 | 2391 | for (;;) { |
---|
2391 | | - unsigned n = dir->i_dir_seq; |
---|
2392 | | - if (!(n & 1) && cmpxchg(&dir->i_dir_seq, n, n + 1) == n) |
---|
| 2392 | + unsigned n = dir->__i_dir_seq; |
---|
| 2393 | + if (!(n & 1) && cmpxchg(&dir->__i_dir_seq, n, n + 1) == n) |
---|
2393 | 2394 | return n; |
---|
2394 | 2395 | cpu_relax(); |
---|
2395 | 2396 | } |
---|
.. | .. |
---|
2397 | 2398 | |
---|
2398 | 2399 | static inline void end_dir_add(struct inode *dir, unsigned n) |
---|
2399 | 2400 | { |
---|
2400 | | - smp_store_release(&dir->i_dir_seq, n + 2); |
---|
| 2401 | + smp_store_release(&dir->__i_dir_seq, n + 2); |
---|
| 2402 | + preempt_enable_rt(); |
---|
2401 | 2403 | } |
---|
2402 | 2404 | |
---|
2403 | 2405 | static void d_wait_lookup(struct dentry *dentry) |
---|
2404 | 2406 | { |
---|
2405 | | - if (d_in_lookup(dentry)) { |
---|
2406 | | - DECLARE_WAITQUEUE(wait, current); |
---|
2407 | | - add_wait_queue(dentry->d_wait, &wait); |
---|
2408 | | - do { |
---|
2409 | | - set_current_state(TASK_UNINTERRUPTIBLE); |
---|
2410 | | - spin_unlock(&dentry->d_lock); |
---|
2411 | | - schedule(); |
---|
2412 | | - spin_lock(&dentry->d_lock); |
---|
2413 | | - } while (d_in_lookup(dentry)); |
---|
2414 | | - } |
---|
| 2407 | + struct swait_queue __wait; |
---|
| 2408 | + |
---|
| 2409 | + if (!d_in_lookup(dentry)) |
---|
| 2410 | + return; |
---|
| 2411 | + |
---|
| 2412 | + INIT_LIST_HEAD(&__wait.task_list); |
---|
| 2413 | + do { |
---|
| 2414 | + prepare_to_swait_exclusive(dentry->d_wait, &__wait, TASK_UNINTERRUPTIBLE); |
---|
| 2415 | + spin_unlock(&dentry->d_lock); |
---|
| 2416 | + schedule(); |
---|
| 2417 | + spin_lock(&dentry->d_lock); |
---|
| 2418 | + } while (d_in_lookup(dentry)); |
---|
| 2419 | + finish_swait(dentry->d_wait, &__wait); |
---|
2415 | 2420 | } |
---|
2416 | 2421 | |
---|
2417 | 2422 | struct dentry *d_alloc_parallel(struct dentry *parent, |
---|
2418 | 2423 | const struct qstr *name, |
---|
2419 | | - wait_queue_head_t *wq) |
---|
| 2424 | + struct swait_queue_head *wq) |
---|
2420 | 2425 | { |
---|
2421 | 2426 | unsigned int hash = name->hash; |
---|
2422 | 2427 | struct hlist_bl_head *b = in_lookup_hash(parent, hash); |
---|
.. | .. |
---|
2430 | 2435 | |
---|
2431 | 2436 | retry: |
---|
2432 | 2437 | rcu_read_lock(); |
---|
2433 | | - seq = smp_load_acquire(&parent->d_inode->i_dir_seq); |
---|
| 2438 | + seq = smp_load_acquire(&parent->d_inode->__i_dir_seq); |
---|
2434 | 2439 | r_seq = read_seqbegin(&rename_lock); |
---|
2435 | 2440 | dentry = __d_lookup_rcu(parent, name, &d_seq); |
---|
2436 | 2441 | if (unlikely(dentry)) { |
---|
.. | .. |
---|
2458 | 2463 | } |
---|
2459 | 2464 | |
---|
2460 | 2465 | hlist_bl_lock(b); |
---|
2461 | | - if (unlikely(READ_ONCE(parent->d_inode->i_dir_seq) != seq)) { |
---|
| 2466 | + if (unlikely(READ_ONCE(parent->d_inode->__i_dir_seq) != seq)) { |
---|
2462 | 2467 | hlist_bl_unlock(b); |
---|
2463 | 2468 | rcu_read_unlock(); |
---|
2464 | 2469 | goto retry; |
---|
.. | .. |
---|
2531 | 2536 | hlist_bl_lock(b); |
---|
2532 | 2537 | dentry->d_flags &= ~DCACHE_PAR_LOOKUP; |
---|
2533 | 2538 | __hlist_bl_del(&dentry->d_u.d_in_lookup_hash); |
---|
2534 | | - wake_up_all(dentry->d_wait); |
---|
| 2539 | + swake_up_all(dentry->d_wait); |
---|
2535 | 2540 | dentry->d_wait = NULL; |
---|
2536 | 2541 | hlist_bl_unlock(b); |
---|
2537 | 2542 | INIT_HLIST_NODE(&dentry->d_u.d_alias); |
---|
.. | .. |
---|
3044 | 3049 | |
---|
3045 | 3050 | static void __init dcache_init_early(void) |
---|
3046 | 3051 | { |
---|
| 3052 | + unsigned int loop; |
---|
| 3053 | + |
---|
3047 | 3054 | /* If hashes are distributed across NUMA nodes, defer |
---|
3048 | 3055 | * hash allocation until vmalloc space is available. |
---|
3049 | 3056 | */ |
---|
.. | .. |
---|
3060 | 3067 | NULL, |
---|
3061 | 3068 | 0, |
---|
3062 | 3069 | 0); |
---|
| 3070 | + |
---|
| 3071 | + for (loop = 0; loop < (1U << d_hash_shift); loop++) |
---|
| 3072 | + INIT_HLIST_BL_HEAD(dentry_hashtable + loop); |
---|
| 3073 | + |
---|
3063 | 3074 | d_hash_shift = 32 - d_hash_shift; |
---|
3064 | 3075 | } |
---|
3065 | 3076 | |
---|
3066 | 3077 | static void __init dcache_init(void) |
---|
3067 | 3078 | { |
---|
| 3079 | + unsigned int loop; |
---|
3068 | 3080 | /* |
---|
3069 | 3081 | * A constructor could be added for stable state like the lists, |
---|
3070 | 3082 | * but it is probably not worth it because of the cache nature |
---|
.. | .. |
---|
3088 | 3100 | NULL, |
---|
3089 | 3101 | 0, |
---|
3090 | 3102 | 0); |
---|
| 3103 | + |
---|
| 3104 | + for (loop = 0; loop < (1U << d_hash_shift); loop++) |
---|
| 3105 | + INIT_HLIST_BL_HEAD(dentry_hashtable + loop); |
---|
| 3106 | + |
---|
3091 | 3107 | d_hash_shift = 32 - d_hash_shift; |
---|
3092 | 3108 | } |
---|
3093 | 3109 | |
---|