mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 10:37:35 +03:00
Batch free zpl_posix_acl_release
Currently every calls to zpl_posix_acl_release will schedule a delayed task, and each delayed task will add a timer. This used to be fine except for possibly bad performance impact. However, in Linux 4.8, a new timer wheel implementation[1] is introduced. In this new implementation, the larger the delay, the less accuracy the timer is. So when we have a flood of timer from zpl_posix_acl_release, they will expire at the same time. Couple with the fact that task_expire will do linear search with lock held. This causes an extreme amount of contention inside interrupt and would actually lockup the system. We fix this by doing batch free to prevent a flood of delayed task. Every call to zpl_posix_acl_release will put the posix_acl to be freed on a lockless list. Every batch window, 1 sec, the zpl_posix_acl_free will fire up and free every posix_acl that passed the grace period on the list. This way, we only have one delayed task every second. [1] https://lwn.net/Articles/646950/ Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
This commit is contained in:
committed by
Brian Behlendorf
parent
83bf769d50
commit
8e71ab99dc
@@ -212,10 +212,7 @@ lseek_execute(
|
||||
|
||||
#else
|
||||
|
||||
static inline void
|
||||
zpl_posix_acl_free(void *arg) {
|
||||
kfree(arg);
|
||||
}
|
||||
void zpl_posix_acl_release_impl(struct posix_acl *);
|
||||
|
||||
static inline void
|
||||
zpl_posix_acl_release(struct posix_acl *acl)
|
||||
@@ -223,10 +220,8 @@ zpl_posix_acl_release(struct posix_acl *acl)
|
||||
if ((acl == NULL) || (acl == ACL_NOT_CACHED))
|
||||
return;
|
||||
|
||||
if (atomic_dec_and_test(&acl->a_refcount)) {
|
||||
taskq_dispatch_delay(system_taskq, zpl_posix_acl_free, acl,
|
||||
TQ_SLEEP, ddi_get_lbolt() + 60*HZ);
|
||||
}
|
||||
if (atomic_dec_and_test(&acl->a_refcount))
|
||||
zpl_posix_acl_release_impl(acl);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
||||
Reference in New Issue
Block a user