Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137931565
D20645.id59121.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D20645.id59121.diff
View Options
Index: sys/kern/kern_rangelock.c
===================================================================
--- sys/kern/kern_rangelock.c
+++ sys/kern/kern_rangelock.c
@@ -141,15 +141,33 @@
static void
rangelock_unlock_locked(struct rangelock *lock, struct rl_q_entry *entry,
- struct mtx *ilk)
+ struct mtx *ilk, bool do_calc_block)
{
MPASS(lock != NULL && entry != NULL && ilk != NULL);
mtx_assert(ilk, MA_OWNED);
- KASSERT(entry != lock->rl_currdep, ("stuck currdep"));
+
+ if (!do_calc_block) {
+ /*
+ * This is the case where rangelock_enqueue() has been called
+ * with trylock == true and just inserted this entry in the
+ * queue.
+ * If rl_currdep is this entry, rl_currdep needs to
+ * be set to the next entry in the rl_waiters list.
+ * However, since this entry is the last entry in the
+ * list, the next entry is NULL.
+ */
+ if (lock->rl_currdep == entry) {
+ KASSERT(TAILQ_NEXT(lock->rl_currdep, rl_q_link) == NULL,
+ ("rangelock_enqueue: next entry not NULL"));
+ lock->rl_currdep = NULL;
+ }
+ } else
+ KASSERT(entry != lock->rl_currdep, ("stuck currdep"));
TAILQ_REMOVE(&lock->rl_waiters, entry, rl_q_link);
- rangelock_calc_block(lock);
+ if (do_calc_block)
+ rangelock_calc_block(lock);
mtx_unlock(ilk);
if (curthread->td_rlqe == NULL)
curthread->td_rlqe = entry;
@@ -164,7 +182,7 @@
MPASS(lock != NULL && cookie != NULL && ilk != NULL);
mtx_lock(ilk);
- rangelock_unlock_locked(lock, cookie, ilk);
+ rangelock_unlock_locked(lock, cookie, ilk, true);
}
/*
@@ -185,7 +203,7 @@
mtx_lock(ilk);
if (entry->rl_q_end == end) {
- rangelock_unlock_locked(lock, cookie, ilk);
+ rangelock_unlock_locked(lock, cookie, ilk, true);
return (NULL);
}
entry->rl_q_end = end;
@@ -196,11 +214,11 @@
/*
* Add the lock request to the queue of the pending requests for
- * rangelock. Sleep until the request can be granted.
+ * rangelock. Sleep until the request can be granted unless trylock == true.
*/
static void *
rangelock_enqueue(struct rangelock *lock, off_t start, off_t end, int mode,
- struct mtx *ilk)
+ struct mtx *ilk, bool trylock)
{
struct rl_q_entry *entry;
struct thread *td;
@@ -226,11 +244,28 @@
*/
TAILQ_INSERT_TAIL(&lock->rl_waiters, entry, rl_q_link);
+ /*
+ * If rl_currdep == NULL, there is no entry waiting for a conflicting
+ * range to be resolved, so set rl_currdep to this entry. If there is
+ * no conflicting entry for this entry, rl_currdep will be set back to
+ * NULL by rangelock_calc_block().
+ */
if (lock->rl_currdep == NULL)
lock->rl_currdep = entry;
rangelock_calc_block(lock);
- while (!(entry->rl_q_flags & RL_LOCK_GRANTED))
+ while (!(entry->rl_q_flags & RL_LOCK_GRANTED)) {
+ if (trylock) {
+ /*
+ * For this case, the range is not actually locked
+ * yet, but removal from the list requires the same
+ * steps, except for not doing a rangelock_calc_block()
+ * call, since rangelock_calc_block() was called above.
+ */
+ rangelock_unlock_locked(lock, entry, ilk, false);
+ return (NULL);
+ }
msleep(entry, ilk, 0, "range", 0);
+ }
mtx_unlock(ilk);
return (entry);
}
@@ -239,12 +274,28 @@
rangelock_rlock(struct rangelock *lock, off_t start, off_t end, struct mtx *ilk)
{
- return (rangelock_enqueue(lock, start, end, RL_LOCK_READ, ilk));
+ return (rangelock_enqueue(lock, start, end, RL_LOCK_READ, ilk, false));
+}
+
+void *
+rangelock_tryrlock(struct rangelock *lock, off_t start, off_t end,
+ struct mtx *ilk)
+{
+
+ return (rangelock_enqueue(lock, start, end, RL_LOCK_READ, ilk, true));
}
void *
rangelock_wlock(struct rangelock *lock, off_t start, off_t end, struct mtx *ilk)
{
- return (rangelock_enqueue(lock, start, end, RL_LOCK_WRITE, ilk));
+ return (rangelock_enqueue(lock, start, end, RL_LOCK_WRITE, ilk, false));
+}
+
+void *
+rangelock_trywlock(struct rangelock *lock, off_t start, off_t end,
+ struct mtx *ilk)
+{
+
+ return (rangelock_enqueue(lock, start, end, RL_LOCK_WRITE, ilk, true));
}
Index: sys/sys/rangelock.h
===================================================================
--- sys/sys/rangelock.h
+++ sys/sys/rangelock.h
@@ -75,8 +75,12 @@
off_t start, off_t end, struct mtx *ilk);
void *rangelock_rlock(struct rangelock *lock, off_t start, off_t end,
struct mtx *ilk);
+void *rangelock_tryrlock(struct rangelock *lock, off_t start,
+ off_t end, struct mtx *ilk);
void *rangelock_wlock(struct rangelock *lock, off_t start, off_t end,
struct mtx *ilk);
+void *rangelock_trywlock(struct rangelock *lock, off_t start,
+ off_t end, struct mtx *ilk);
void rlqentry_free(struct rl_q_entry *rlqe);
#endif /* _KERNEL */
Index: sys/sys/vnode.h
===================================================================
--- sys/sys/vnode.h
+++ sys/sys/vnode.h
@@ -720,8 +720,12 @@
VI_MTX(vp))
#define vn_rangelock_rlock(vp, start, end) \
rangelock_rlock(&(vp)->v_rl, (start), (end), VI_MTX(vp))
+#define vn_rangelock_tryrlock(vp, start, end) \
+ rangelock_tryrlock(&(vp)->v_rl, (start), (end), VI_MTX(vp))
#define vn_rangelock_wlock(vp, start, end) \
rangelock_wlock(&(vp)->v_rl, (start), (end), VI_MTX(vp))
+#define vn_rangelock_trywlock(vp, start, end) \
+ rangelock_trywlock(&(vp)->v_rl, (start), (end), VI_MTX(vp))
int vfs_cache_lookup(struct vop_lookup_args *ap);
void vfs_timestamp(struct timespec *);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 28, 9:33 AM (15 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26280008
Default Alt Text
D20645.id59121.diff (5 KB)
Attached To
Mode
D20645: add non-blocking variants of rangelock_rlock() and rangelock_wlock()
Attached
Detach File
Event Timeline
Log In to Comment