Whamcloud - gitweb
git://git.whamcloud.com
/
fs
/
lustre-release.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
| inline |
side by side
LU-2744 build: fix race issues thanks to oap_lock
[fs/lustre-release.git]
/
lustre
/
osc
/
osc_cache.c
diff --git
a/lustre/osc/osc_cache.c
b/lustre/osc/osc_cache.c
index
b462fcc
..
11a5e0e
100644
(file)
--- a/
lustre/osc/osc_cache.c
+++ b/
lustre/osc/osc_cache.c
@@
-309,7
+309,7
@@
static struct osc_extent *osc_extent_alloc(struct osc_object *obj)
{
struct osc_extent *ext;
- OBD_SLAB_ALLOC_PTR_GFP(ext, osc_extent_kmem,
CFS_ALLOC_STD
);
+ OBD_SLAB_ALLOC_PTR_GFP(ext, osc_extent_kmem,
GFP_IOFS
);
if (ext == NULL)
return NULL;
@@
-505,7
+505,7
@@
static int osc_extent_merge(const struct lu_env *env, struct osc_extent *cur,
return -ERANGE;
LASSERT(cur->oe_osclock == victim->oe_osclock);
- ppc_bits = osc_cli(obj)->cl_chunkbits -
CFS_PAG
E_SHIFT;
+ ppc_bits = osc_cli(obj)->cl_chunkbits -
PAGE_CACH
E_SHIFT;
chunk_start = cur->oe_start >> ppc_bits;
chunk_end = cur->oe_end >> ppc_bits;
if (chunk_start != (victim->oe_end >> ppc_bits) + 1 &&
@@
-612,8
+612,8
@@
struct osc_extent *osc_extent_find(const struct lu_env *env,
LASSERT(lock != NULL);
LASSERT(lock->cll_descr.cld_mode >= CLM_WRITE);
- LASSERT(cli->cl_chunkbits >=
CFS_PAG
E_SHIFT);
- ppc_bits = cli->cl_chunkbits -
CFS_PAG
E_SHIFT;
+ LASSERT(cli->cl_chunkbits >=
PAGE_CACH
E_SHIFT);
+ ppc_bits = cli->cl_chunkbits -
PAGE_CACH
E_SHIFT;
chunk_mask = ~((1 << ppc_bits) - 1);
chunksize = 1 << cli->cl_chunkbits;
chunk = index >> ppc_bits;
@@
-827,8
+827,8
@@
int osc_extent_finish(const struct lu_env *env, struct osc_extent *ext,
if (!sent) {
lost_grant = ext->oe_grants;
- } else if (blocksize <
CFS_PAG
E_SIZE &&
- last_count !=
CFS_PAG
E_SIZE) {
+ } else if (blocksize <
PAGE_CACH
E_SIZE &&
+ last_count !=
PAGE_CACH
E_SIZE) {
/* For short writes we shouldn't count parts of pages that
* span a whole chunk on the OST side, or our accounting goes
* wrong. Should match the code in filter_grant_check. */
@@
-838,7
+838,7
@@
int osc_extent_finish(const struct lu_env *env, struct osc_extent *ext,
if (end)
count += blocksize - end;
- lost_grant =
CFS_PAG
E_SIZE - count;
+ lost_grant =
PAGE_CACH
E_SIZE - count;
}
if (ext->oe_grants > 0)
osc_free_grant(cli, nr_pages, lost_grant);
@@
-920,7
+920,8
@@
static int osc_extent_truncate(struct osc_extent *ext, pgoff_t trunc_index,
struct osc_async_page *oap;
struct osc_async_page *tmp;
int pages_in_chunk = 0;
- int ppc_bits = cli->cl_chunkbits - CFS_PAGE_SHIFT;
+ int ppc_bits = cli->cl_chunkbits -
+ PAGE_CACHE_SHIFT;
__u64 trunc_chunk = trunc_index >> ppc_bits;
int grants = 0;
int nr_pages = 0;
@@
-1077,16
+1078,20
@@
static int osc_extent_make_ready(const struct lu_env *env,
if (!(last->oap_async_flags & ASYNC_COUNT_STABLE)) {
last->oap_count = osc_refresh_count(env, last, OBD_BRW_WRITE);
LASSERT(last->oap_count > 0);
- LASSERT(last->oap_page_off + last->oap_count <= CFS_PAGE_SIZE);
+ LASSERT(last->oap_page_off + last->oap_count <= PAGE_CACHE_SIZE);
+ spin_lock(&last->oap_lock);
last->oap_async_flags |= ASYNC_COUNT_STABLE;
+ spin_unlock(&last->oap_lock);
}
/* for the rest of pages, we don't need to call osf_refresh_count()
* because it's known they are not the last page */
cfs_list_for_each_entry(oap, &ext->oe_pages, oap_pending_item) {
if (!(oap->oap_async_flags & ASYNC_COUNT_STABLE)) {
- oap->oap_count = CFS_PAGE_SIZE - oap->oap_page_off;
+ oap->oap_count = PAGE_CACHE_SIZE - oap->oap_page_off;
+ spin_lock(&oap->oap_lock);
oap->oap_async_flags |= ASYNC_COUNT_STABLE;
+ spin_unlock(&oap->oap_lock);
}
}
@@
-1109,7
+1114,7
@@
static int osc_extent_expand(struct osc_extent *ext, pgoff_t index, int *grants)
struct osc_object *obj = ext->oe_obj;
struct client_obd *cli = osc_cli(obj);
struct osc_extent *next;
- int ppc_bits = cli->cl_chunkbits -
CFS_PAG
E_SHIFT;
+ int ppc_bits = cli->cl_chunkbits -
PAGE_CACH
E_SHIFT;
pgoff_t chunk = index >> ppc_bits;
pgoff_t end_chunk;
pgoff_t end_index;
@@
-1241,9
+1246,9
@@
static int osc_refresh_count(const struct lu_env *env,
return 0;
else if (cl_offset(obj, page->cp_index + 1) > kms)
/* catch sub-page write at end of file */
- return kms %
CFS_PAG
E_SIZE;
+ return kms %
PAGE_CACH
E_SIZE;
else
- return
CFS_PAG
E_SIZE;
+ return
PAGE_CACH
E_SIZE;
}
static int osc_completion(const struct lu_env *env, struct osc_async_page *oap,
@@
-1308,28
+1313,32
@@
static int osc_completion(const struct lu_env *env, struct osc_async_page *oap,
RETURN(0);
}
-#define OSC_DUMP_GRANT(
cli, fmt, args...) do {
\
+#define OSC_DUMP_GRANT(
lvl, cli, fmt, args...) do {
\
struct client_obd *__tmp = (cli); \
- CDEBUG(D_CACHE, "%s: { dirty: %ld/%ld dirty_pages: %d/%d " \
- "dropped: %ld avail: %ld, reserved: %ld, flight: %d } " fmt, \
+ CDEBUG(lvl, "%s: grant { dirty: %ld/%ld dirty_pages: %d/%d " \
+ "dropped: %ld avail: %ld, reserved: %ld, flight: %d } " \
+ "lru {in list: %d, left: %d, waiters: %d }" fmt, \
__tmp->cl_import->imp_obd->obd_name, \
__tmp->cl_dirty, __tmp->cl_dirty_max, \
cfs_atomic_read(&obd_dirty_pages), obd_max_dirty_pages, \
__tmp->cl_lost_grant, __tmp->cl_avail_grant, \
- __tmp->cl_reserved_grant, __tmp->cl_w_in_flight, ##args); \
+ __tmp->cl_reserved_grant, __tmp->cl_w_in_flight, \
+ cfs_atomic_read(&__tmp->cl_lru_in_list), \
+ cfs_atomic_read(&__tmp->cl_lru_busy), \
+ cfs_atomic_read(&__tmp->cl_lru_shrinkers), ##args); \
} while (0)
/* caller must hold loi_list_lock */
static void osc_consume_write_grant(struct client_obd *cli,
struct brw_page *pga)
{
- LASSERT
_SPIN_LOCKED(&cli->cl_loi_list_lock.lock
);
+ LASSERT
(spin_is_locked(&cli->cl_loi_list_lock.lock)
);
LASSERT(!(pga->flag & OBD_BRW_FROM_GRANT));
cfs_atomic_inc(&obd_dirty_pages);
- cli->cl_dirty +=
CFS_PAG
E_SIZE;
+ cli->cl_dirty +=
PAGE_CACH
E_SIZE;
pga->flag |= OBD_BRW_FROM_GRANT;
CDEBUG(D_CACHE, "using %lu grant credits for brw %p page %p\n",
-
CFS_PAG
E_SIZE, pga, pga->pg);
+
PAGE_CACH
E_SIZE, pga, pga->pg);
osc_update_next_shrink(cli);
}
@@
-1340,7
+1349,7
@@
static void osc_release_write_grant(struct client_obd *cli,
{
ENTRY;
- LASSERT
_SPIN_LOCKED(&cli->cl_loi_list_lock.lock
);
+ LASSERT
(spin_is_locked(&cli->cl_loi_list_lock.lock)
);
if (!(pga->flag & OBD_BRW_FROM_GRANT)) {
EXIT;
return;
@@
-1348,11
+1357,11
@@
static void osc_release_write_grant(struct client_obd *cli,
pga->flag &= ~OBD_BRW_FROM_GRANT;
cfs_atomic_dec(&obd_dirty_pages);
- cli->cl_dirty -=
CFS_PAG
E_SIZE;
+ cli->cl_dirty -=
PAGE_CACH
E_SIZE;
if (pga->flag & OBD_BRW_NOCACHE) {
pga->flag &= ~OBD_BRW_NOCACHE;
cfs_atomic_dec(&obd_dirty_transit_pages);
- cli->cl_dirty_transit -=
CFS_PAG
E_SIZE;
+ cli->cl_dirty_transit -=
PAGE_CACH
E_SIZE;
}
EXIT;
}
@@
-1408,7
+1417,7
@@
void osc_unreserve_grant(struct client_obd *cli,
* used, we should return these grants to OST. There're two cases where grants
* can be lost:
* 1. truncate;
- * 2. blocksize at OST is less than
CFS_PAG
E_SIZE and a partial page was
+ * 2. blocksize at OST is less than
PAGE_CACH
E_SIZE and a partial page was
* written. In this case OST may use less chunks to serve this partial
* write. OSTs don't actually know the page size on the client side. so
* clients have to calculate lost grant by the blocksize on the OST.
@@
-1421,7
+1430,7
@@
static void osc_free_grant(struct client_obd *cli, unsigned int nr_pages,
client_obd_list_lock(&cli->cl_loi_list_lock);
cfs_atomic_sub(nr_pages, &obd_dirty_pages);
- cli->cl_dirty -= nr_pages <<
CFS_PAG
E_SHIFT;
+ cli->cl_dirty -= nr_pages <<
PAGE_CACH
E_SHIFT;
cli->cl_lost_grant += lost_grant;
if (cli->cl_avail_grant < grant && cli->cl_lost_grant >= grant) {
/* borrow some grant from truncate to avoid the case that
@@
-1457,17
+1466,17
@@
static int osc_enter_cache_try(struct client_obd *cli,
{
int rc;
- OSC_DUMP_GRANT(cli, "need:%d.\n", bytes);
+ OSC_DUMP_GRANT(
D_CACHE,
cli, "need:%d.\n", bytes);
rc = osc_reserve_grant(cli, bytes);
if (rc < 0)
return 0;
- if (cli->cl_dirty +
CFS_PAG
E_SIZE <= cli->cl_dirty_max &&
+ if (cli->cl_dirty +
PAGE_CACH
E_SIZE <= cli->cl_dirty_max &&
cfs_atomic_read(&obd_dirty_pages) + 1 <= obd_max_dirty_pages) {
osc_consume_write_grant(cli, &oap->oap_brw_page);
if (transient) {
- cli->cl_dirty_transit +=
CFS_PAG
E_SIZE;
+ cli->cl_dirty_transit +=
PAGE_CACH
E_SIZE;
cfs_atomic_inc(&obd_dirty_transit_pages);
oap->oap_brw_flags |= OBD_BRW_NOCACHE;
}
@@
-1501,18
+1510,19
@@
static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli,
struct osc_object *osc = oap->oap_obj;
struct lov_oinfo *loi = osc->oo_oinfo;
struct osc_cache_waiter ocw;
- struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
+ struct l_wait_info lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(600), NULL,
+ LWI_ON_SIGNAL_NOOP, NULL);
int rc = -EDQUOT;
ENTRY;
- OSC_DUMP_GRANT(cli, "need:%d.\n", bytes);
+ OSC_DUMP_GRANT(
D_CACHE,
cli, "need:%d.\n", bytes);
client_obd_list_lock(&cli->cl_loi_list_lock);
/* force the caller to try sync io. this can jump the list
* of queued writes and create a discontiguous rpc stream */
if (OBD_FAIL_CHECK(OBD_FAIL_OSC_NO_GRANT) ||
- cli->cl_dirty_max <
CFS_PAG
E_SIZE ||
+ cli->cl_dirty_max <
PAGE_CACH
E_SIZE ||
cli->cl_ar.ar_force_sync || loi->loi_ar.ar_force_sync)
GOTO(out, rc = -EDQUOT);
@@
-1543,8
+1553,26
@@
static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli,
client_obd_list_lock(&cli->cl_loi_list_lock);
- /* l_wait_event is interrupted by signal */
+ /* l_wait_event is interrupted by signal
, or timed out
*/
if (rc < 0) {
+ switch (rc) {
+ case -ETIMEDOUT:
+ OSC_DUMP_GRANT(D_ERROR, cli,
+ "try to reserve %d.\n", bytes);
+ osc_extent_tree_dump(D_ERROR, osc);
+ rc = -EDQUOT;
+ break;
+ case -EINTR:
+ /* Ensures restartability - LU-3581 */
+ rc = -ERESTARTSYS;
+ break;
+ default:
+ CDEBUG(D_CACHE, "%s: event for cache space @"
+ " %p never arrived due to %d\n",
+ cli->cl_import->imp_obd->obd_name,
+ &ocw, rc);
+ break;
+ }
cfs_list_del_init(&ocw.ocw_entry);
GOTO(out, rc);
}
@@
-1560,7
+1588,7
@@
static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli,
EXIT;
out:
client_obd_list_unlock(&cli->cl_loi_list_lock);
- OSC_DUMP_GRANT(cli, "returned %d.\n", rc);
+ OSC_DUMP_GRANT(
D_CACHE,
cli, "returned %d.\n", rc);
RETURN(rc);
}
@@
-1577,7
+1605,7
@@
void osc_wake_cache_waiters(struct client_obd *cli)
ocw->ocw_rc = -EDQUOT;
/* we can't dirty more */
- if ((cli->cl_dirty +
CFS_PAG
E_SIZE > cli->cl_dirty_max) ||
+ if ((cli->cl_dirty +
PAGE_CACH
E_SIZE > cli->cl_dirty_max) ||
(cfs_atomic_read(&obd_dirty_pages) + 1 >
obd_max_dirty_pages)) {
CDEBUG(D_CACHE, "no dirty room: dirty: %ld "
@@
-2063,7
+2091,7
@@
static void osc_check_rpcs(const struct lu_env *env, struct client_obd *cli,
while ((osc = osc_next_obj(cli)) != NULL) {
struct cl_object *obj = osc2cl(osc);
- struct lu_ref_link
*
link;
+ struct lu_ref_link link;
OSC_IO_DEBUG(osc, "%lu in flight\n", rpcs_in_flight(cli));
@@
-2074,7
+2102,8
@@
static void osc_check_rpcs(const struct lu_env *env, struct client_obd *cli,
cl_object_get(obj);
client_obd_list_unlock(&cli->cl_loi_list_lock);
- link = lu_object_ref_add(&obj->co_lu, "check", cfs_current());
+ lu_object_ref_add_at(&obj->co_lu, &link, "check",
+ cfs_current());
/* attempt some read/write balancing by alternating between
* reads and writes in an object. The makes_rpc checks here
@@
-2115,7
+2144,8
@@
static void osc_check_rpcs(const struct lu_env *env, struct client_obd *cli,
osc_object_unlock(osc);
osc_list_maint(cli, osc);
- lu_object_ref_del_at(&obj->co_lu, link, "check", cfs_current());
+ lu_object_ref_del_at(&obj->co_lu, &link, "check",
+ cfs_current());
cl_object_put(env, obj);
client_obd_list_lock(&cli->cl_loi_list_lock);
@@
-2160,7
+2190,7
@@
void osc_io_unplug(const struct lu_env *env, struct client_obd *cli,
}
int osc_prep_async_page(struct osc_object *osc, struct osc_page *ops,
-
cfs_page_t
*page, loff_t offset)
+
struct page
*page, loff_t offset)
{
struct obd_export *exp = osc_export(osc);
struct osc_async_page *oap = &ops->ops_oap;
@@
-2247,6
+2277,8
@@
int osc_queue_async_io(const struct lu_env *env, struct cl_io *io,
oap->oap_cmd = cmd;
oap->oap_page_off = ops->ops_from;
oap->oap_count = ops->ops_to - ops->ops_from;
+ /* No need to hold a lock here,
+ * since this page is not in any list yet. */
oap->oap_async_flags = 0;
oap->oap_brw_flags = brw_flags;
@@
-2441,7
+2473,7
@@
int osc_flush_async_page(const struct lu_env *env, struct cl_io *io,
oap->oap_async_flags |= ASYNC_READY|ASYNC_URGENT;
spin_unlock(&oap->oap_lock);
- if (
cfs_
memory_pressure_get())
+ if (memory_pressure_get())
ext->oe_memalloc = 1;
ext->oe_urgent = 1;
@@
-2908,7
+2940,7
@@
int osc_cache_writeback_range(const struct lu_env *env, struct osc_object *obj,
result = rc;
}
- OSC_IO_DEBUG(obj, "
cache page out.\n"
);
+ OSC_IO_DEBUG(obj, "
pageout [%lu, %lu], %d.\n", start, end, result
);
RETURN(result);
}