Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/os/freebsd/spl/sys/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,9 @@ struct opensolaris_utsname {
#define task_io_account_read(n)
#define task_io_account_write(n)

/*
* Check if the current thread is a memory reclaim thread.
*/
extern int current_is_reclaim_thread(void);

#endif /* _OPENSOLARIS_SYS_MISC_H_ */
6 changes: 6 additions & 0 deletions include/os/linux/spl/sys/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@
#define _OS_LINUX_SPL_MISC_H

#include <linux/kobject.h>
#include <linux/swap.h>

extern void spl_signal_kobj_evt(struct block_device *bdev);

/*
* Check if the current thread is a memory reclaim thread.
*/
extern int current_is_reclaim_thread(void);

#endif
5 changes: 5 additions & 0 deletions include/sys/zfs_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,11 @@ typedef pthread_t kthread_t;
#define thread_join(t) pthread_join((pthread_t)(t), NULL)

#define newproc(f, a, cid, pri, ctp, pid) (ENOSYS)
/*
* Check if the current thread is a memory reclaim thread.
* Always returns false in userspace (no memory reclaim thread).
*/
#define current_is_reclaim_thread() (0)

/* in libzpool, p0 exists only to have its address taken */
typedef struct proc {
Expand Down
9 changes: 9 additions & 0 deletions module/os/freebsd/spl/spl_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ spl_panic(const char *file, const char *func, int line, const char *fmt, ...)
va_end(ap);
}

/*
* Check if the current thread is a memory reclaim thread.
* Returns true if curproc is pageproc (FreeBSD's page daemon).
*/
int
current_is_reclaim_thread(void)
{
return (curproc == pageproc);
}

SYSINIT(opensolaris_utsname_init, SI_SUB_TUNABLES, SI_ORDER_ANY,
opensolaris_utsname_init, NULL);
12 changes: 12 additions & 0 deletions module/os/linux/spl/spl-thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <sys/kmem.h>
#include <sys/tsd.h>
#include <sys/string.h>
#include <sys/misc.h>

/*
* Thread interfaces
Expand Down Expand Up @@ -197,3 +198,14 @@ issig(void)
}

EXPORT_SYMBOL(issig);

/*
* Check if the current thread is a memory reclaim thread.
* Returns true if current thread is kswapd.
*/
int
current_is_reclaim_thread(void)
{
return (current_is_kswapd());
}
EXPORT_SYMBOL(current_is_reclaim_thread);
10 changes: 9 additions & 1 deletion module/zfs/dbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -866,8 +866,16 @@ dbuf_evict_notify(uint64_t size)
* and grabbing the lock results in massive lock contention.
*/
if (size > dbuf_cache_target_bytes()) {
if (size > dbuf_cache_hiwater_bytes())
/*
* Avoid calling dbuf_evict_one() from memory reclaim context
* (e.g. Linux kswapd, FreeBSD pagedaemon) to prevent deadlocks.
* Memory reclaim threads can get stuck waiting for the dbuf
* hash lock.
*/
if (size > dbuf_cache_hiwater_bytes() &&
!current_is_reclaim_thread()) {
dbuf_evict_one();
}
cv_signal(&dbuf_evict_cv);
}
}
Expand Down