From d758bfd1f6ac16bce930033bf14e4bf7b5567972 Mon Sep 17 00:00:00 2001 From: Stephen Champion Date: Fri, 3 Oct 2014 06:08:49 -0700 Subject: [PATCH] LU-5700 llite: handle concurrent use of cob_transient_pages With the lockless __generic_file_aio_write introduced in LU-1669, ll_direct_IO_26 is no longer protected by the inode i_isem. This renders obsoltete checks that all transient pages have been handled before and after entry, and requires atomic access to their counter. Signed-off-by: Stephen Champion Change-Id: Ie1545b2123a5ca7d9a8cac130ff387fc06955629 Reviewed-on: http://review.whamcloud.com/12179 Tested-by: Jenkins Reviewed-by: Jinshan Xiong Tested-by: Maloo Reviewed-by: Bobi Jam Reviewed-by: Oleg Drokin --- lustre/include/lclient.h | 12 ++++++------ lustre/llite/lcommon_cl.c | 10 +++++----- lustre/llite/rw26.c | 4 ---- lustre/llite/vvp_object.c | 3 ++- lustre/llite/vvp_page.c | 4 ++-- 5 files changed, 15 insertions(+), 18 deletions(-) diff --git a/lustre/include/lclient.h b/lustre/include/lclient.h index cb02a9a..c6ea235 100644 --- a/lustre/include/lclient.h +++ b/lustre/include/lclient.h @@ -207,12 +207,12 @@ struct ccc_object { */ struct list_head cob_pending_list; - /** - * Access this counter is protected by inode->i_sem. Now that - * the lifetime of transient pages must be covered by inode sem, - * we don't need to hold any lock.. - */ - int cob_transient_pages; + /** + * Number of transient pages. This is no longer protected by i_sem, + * and needs to be atomic. This is not actually used for anything, + * and can probably be removed. + */ + atomic_t cob_transient_pages; /** * Number of outstanding mmaps on this file. * diff --git a/lustre/llite/lcommon_cl.c b/lustre/llite/lcommon_cl.c index 510ab9d..338727f 100644 --- a/lustre/llite/lcommon_cl.c +++ b/lustre/llite/lcommon_cl.c @@ -347,13 +347,13 @@ struct lu_object *ccc_object_alloc(const struct lu_env *env, } int ccc_object_init0(const struct lu_env *env, - struct ccc_object *vob, - const struct cl_object_conf *conf) + struct ccc_object *vob, + const struct cl_object_conf *conf) { - vob->cob_inode = conf->coc_inode; - vob->cob_transient_pages = 0; + vob->cob_inode = conf->coc_inode; + atomic_set(&vob->cob_transient_pages, 0); cl_object_page_init(&vob->cob_cl, sizeof(struct ccc_page)); - return 0; + return 0; } int ccc_object_init(const struct lu_env *env, struct lu_object *obj, diff --git a/lustre/llite/rw26.c b/lustre/llite/rw26.c index 046c099..73774ae 100644 --- a/lustre/llite/rw26.c +++ b/lustre/llite/rw26.c @@ -377,7 +377,6 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, struct cl_io *io; struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; - struct ccc_object *obj = cl_inode2ccc(inode); long count = iov_length(iov, nr_segs); long tot_bytes = 0, result = 0; struct ll_inode_info *lli = ll_i2info(inode); @@ -411,7 +410,6 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, io = ccc_env_io(env)->cui_cl.cis_io; LASSERT(io != NULL); - LASSERT(obj->cob_transient_pages == 0); for (seg = 0; seg < nr_segs; seg++) { long iov_left = iov[seg].iov_len; unsigned long user_addr = (unsigned long)iov[seg].iov_base; @@ -471,8 +469,6 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, } } out: - LASSERT(obj->cob_transient_pages == 0); - if (tot_bytes > 0) { struct ccc_io *cio = ccc_env_io(env); diff --git a/lustre/llite/vvp_object.c b/lustre/llite/vvp_object.c index 53c5f12..434e141 100644 --- a/lustre/llite/vvp_object.c +++ b/lustre/llite/vvp_object.c @@ -61,7 +61,8 @@ static int vvp_object_print(const struct lu_env *env, void *cookie, (*p)(env, cookie, "(%s %d %d) inode: %p ", list_empty(&obj->cob_pending_list) ? "-" : "+", - obj->cob_transient_pages, atomic_read(&obj->cob_mmap_cnt), + atomic_read(&obj->cob_transient_pages), + atomic_read(&obj->cob_mmap_cnt), inode); if (inode) { lli = ll_i2info(inode); diff --git a/lustre/llite/vvp_page.c b/lustre/llite/vvp_page.c index cf32538..2b384d8 100644 --- a/lustre/llite/vvp_page.c +++ b/lustre/llite/vvp_page.c @@ -495,7 +495,7 @@ static void vvp_transient_page_fini(const struct lu_env *env, struct ccc_object *clobj = cl2ccc(clp->cp_obj); vvp_page_fini_common(cp); - clobj->cob_transient_pages--; + atomic_dec(&clobj->cob_transient_pages); } static const struct cl_page_operations vvp_transient_page_ops = { @@ -544,7 +544,7 @@ int vvp_page_init(const struct lu_env *env, struct cl_object *obj, cl_page_slice_add(page, &cpg->cpg_cl, obj, index, &vvp_transient_page_ops); - clobj->cob_transient_pages++; + atomic_inc(&clobj->cob_transient_pages); } return 0; } -- 1.8.3.1