fs-test 44 shows a problem when multiple threads access an FSFS txn, the txn_dir_cache makes it possible for changes to be lost. Today I have been seeing this test XPASS instead of XFAIL about 1 time in 30 when running "./fs-test --parallel". I don't understand why. I see this with 1.9.x and trunk, I am running the tests on a RAM disk, I still see the XPASS if I go back to r1617500 when the XFAIL was introduced.
The test creates a txn, makes a change, then creates an additional thread that makes a second change, waits for the additional thread to complete, commits the txn. Finally the test looks for the change made by the additional thread to be present in the revision and is an XFAIL because that change is not usually present. When I see the XPASS the change is present. It is possible to make the test always XPASS by setting fs->fsap_data->txn_dir_cache to NULL just before the commit, but if I patch the code I see that is not happening when I see the random XPASS. I have tried increasing the size of the FSFS memory cache by a factor of 100 and the random XPASS still occurs. If I apply the patch below to print details of the cache the XFAIL is usually: reads: 0 writes: 0 hits: 0 pretend: 0 reads: 3 writes: 2 hits: 1 pretend: 0 reads: 3 writes: 2 hits: 1 pretend: 0 ../src-1.9/subversion/tests/libsvn_fs/fs-test.c:5705: (apr_err=SVN_ERR_TEST_FAILED) svn_tests: E200006: assertion 'value && !strcmp(value->data, "value")' failed at ../src-1.9/subversion/tests/libsvn_fs/fs-test.c:5705 XFAIL: lt-fs-test 44: test reopen and modify txn but occasionally I see reads: 0 writes: 0 hits: 0 pretend: 0 reads: 3 writes: 3 hits: 0 pretend: 0 reads: 3 writes: 3 hits: 0 pretend: 0 svn_tests: E200006: assertion 'value && !strcmp(value->data, "value")' failed at ../src-1.9/subversion/tests/libsvn_fs/fs-test.c:5705 XFAIL: lt-fs-test 44: test reopen and modify txn I don't understand why the cache behaviour varies. Although the test uses 2 threads the test is designed so that the threads always do things in the same order. Every XPASS has always been the uncommon 3,3,0,0 rather than the common 3,2,0,0. I only ever see the 3,3,0,0 when running fs-tests with --parallel, in sequential mode it is always 3,2,0,0 and I never see the XPASS. Index: subversion/tests/libsvn_fs/fs-test.c =================================================================== --- subversion/tests/libsvn_fs/fs-test.c (revision 1677901) +++ subversion/tests/libsvn_fs/fs-test.c (working copy) @@ -5628,6 +5628,9 @@ reopen_modify_child(apr_thread_t *tid, void *data) } #endif +#include "../../libsvn_fs_fs/fs.h" +#include "../../libsvn_subr/cache.h" + static svn_error_t * reopen_modify(const svn_test_opts_t *opts, apr_pool_t *pool) @@ -5643,10 +5646,12 @@ reopen_modify(const svn_test_opts_t *opts, apr_status_t status, child_status; apr_threadattr_t *tattr; apr_thread_t *tid; + fs_fs_data_t *ffd; /* Create test repository with greek tree. */ fs_path = "test-reopen-modify"; SVN_ERR(svn_test__create_fs(&fs, fs_path, opts, pool)); + ffd = fs->fsap_data; SVN_ERR(svn_fs_begin_txn(&txn, fs, head_rev, pool)); SVN_ERR(svn_fs_txn_root(&root, txn, pool)); SVN_ERR(svn_test__create_greek_tree(root, pool)); @@ -5656,7 +5661,17 @@ reopen_modify(const svn_test_opts_t *opts, SVN_ERR(svn_fs_begin_txn(&txn, fs, head_rev, pool)); SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool)); SVN_ERR(svn_fs_txn_root(&root, txn, pool)); + printf("reads: %ld writes: %ld hits: %ld pretend: %d\n", + ffd->txn_dir_cache->reads, + ffd->txn_dir_cache->writes, + ffd->txn_dir_cache->hits, + ffd->txn_dir_cache->pretend_empty); SVN_ERR(svn_fs_make_dir(root, "X", pool)); + printf("reads: %ld writes: %ld hits: %ld pretend: %d\n", + ffd->txn_dir_cache->reads, + ffd->txn_dir_cache->writes, + ffd->txn_dir_cache->hits, + ffd->txn_dir_cache->pretend_empty); /* In another thread: reopen fs and txn, and add more changes. This works in BDB and FSX but in FSFS the txn_dir_cache becomes @@ -5677,6 +5692,11 @@ reopen_modify(const svn_test_opts_t *opts, return svn_error_trace(baton.err); /* Commit */ + printf("reads: %ld writes: %ld hits: %ld pretend: %d\n", + ffd->txn_dir_cache->reads, + ffd->txn_dir_cache->writes, + ffd->txn_dir_cache->hits, + ffd->txn_dir_cache->pretend_empty); SVN_ERR(test_commit_txn(&head_rev, txn, NULL, pool)); /* Check for change made by thread. */ -- Philip Martin | Subversion Committer WANdisco // *Non-Stop Data*