try to use other servers or return an error to the
client.
+Severity : minor
+Frequency : occasional
+Bugzilla : 6469
+Description: Multiple concurrent overlapping read+write on multiple SMP nodes
+ caused lock timeout during readahead (since 1.4.2).
+Details : Processes doing readahead might match a lock that hasn't been
+ granted yet if there are overlapping and conflicting lock
+ requests. The readahead process waits on ungranted lock
+ (original lock is CBPENDING), while OST waits for that process
+ to cancel CBPENDING read lock and eventually evicts client.
+
------------------------------------------------------------------------------
2005-06-20 Cluster File Systems, Inc. <info@clusterfs.com>
lock->l_policy_data.l_extent.end < policy->l_extent.end))
continue;
- if (lock->l_resource->lr_type == LDLM_EXTENT &&
- mode == LCK_GROUP &&
+ if (unlikely(mode == LCK_GROUP) &&
+ lock->l_resource->lr_type == LDLM_EXTENT &&
lock->l_policy_data.l_extent.gid != policy->l_extent.gid)
continue;
int rc = 0;
ENTRY;
- if (flags == LDLM_FL_WAIT_NOREPROC)
+ if (flags == LDLM_FL_WAIT_NOREPROC) {
+ LDLM_DEBUG(lock, "client-side enqueue waiting on pending lock");
goto noreproc;
+ }
if (!(flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED |
LDLM_FL_BLOCK_CONV))) {
RA_STAT_MISS,
RA_STAT_DISTANT_READPAGE,
RA_STAT_MISS_IN_WINDOW,
+ RA_STAT_FAILED_GRAB_PAGE,
RA_STAT_FAILED_MATCH,
RA_STAT_DISCARDED,
RA_STAT_ZERO_LEN,
[RA_STAT_MISS] = "misses",
[RA_STAT_DISTANT_READPAGE] = "readpage not consecutive",
[RA_STAT_MISS_IN_WINDOW] = "miss inside window",
+ [RA_STAT_FAILED_GRAB_PAGE] = "failed grab_cache_page",
[RA_STAT_FAILED_MATCH] = "failed lock match",
[RA_STAT_DISCARDED] = "read but discarded",
[RA_STAT_ZERO_LEN] = "zero length file",
page_extent.l_extent.start = (__u64)page->index << PAGE_CACHE_SHIFT;
page_extent.l_extent.end =
page_extent.l_extent.start + PAGE_CACHE_SIZE - 1;
- flags = LDLM_FL_TEST_LOCK;
- if (!(fd_flags&LL_FILE_READAHEAD))
- flags |= LDLM_FL_CBPENDING | LDLM_FL_BLOCK_GRANTED;
+ flags = LDLM_FL_TEST_LOCK | LDLM_FL_BLOCK_GRANTED;
+ if (!(fd_flags & LL_FILE_READAHEAD))
+ flags |= LDLM_FL_CBPENDING
matches = obd_match(ll_i2sbi(inode)->ll_osc_exp,
ll_i2info(inode)->lli_smd, LDLM_EXTENT,
&page_extent, LCK_PR | LCK_PW, &flags, inode,
/* skip locked pages from previous readpage calls */
page = grab_cache_page_nowait_gfp(mapping, i, gfp_mask);
if (page == NULL) {
+ ll_ra_stats_inc(mapping, RA_STAT_FAILED_GRAB_PAGE);
CDEBUG(D_READA, "g_c_p_n failed\n");
continue;
}
goto next_page;
/* bail when we hit the end of the lock. */
- if ((rc = ll_page_matches(page, flags|LL_FILE_READAHEAD)) <= 0) {
+ if ((rc = ll_page_matches(page, flags|LL_FILE_READAHEAD)) <= 0){
LL_CDEBUG_PAGE(D_READA | D_PAGE, page,
"lock match failed: rc %d\n", rc);
ll_ra_stats_inc(mapping, RA_STAT_FAILED_MATCH);
RETURN(rc);
}
-#define ASSERT_LSM_MAGIC(lsmp) \
-do { \
- LASSERT((lsmp) != NULL); \
+#define ASSERT_LSM_MAGIC(lsmp) \
+do { \
+ LASSERT((lsmp) != NULL); \
LASSERTF((lsmp)->lsm_magic == LOV_MAGIC, "%p->lsm_magic=%x\n", \
- (lsmp), (lsmp)->lsm_magic); \
+ (lsmp), (lsmp)->lsm_magic); \
} while (0)
static int lov_destroy(struct obd_export *exp, struct obdo *oa,