performance/quick-read: handle rollover of generation counter

Change-Id: I37a6e0efda430b70d03dd431c35bef23b3d16361
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
Updates: bz#1512691
This commit is contained in:
Raghavendra G 2018-08-11 19:18:32 +05:30
parent 212075b662
commit cde1d39399
2 changed files with 108 additions and 36 deletions

View File

@ -16,11 +16,18 @@
#include "atomic.h"
typedef struct qr_local {
inode_t *inode;
inode_t *inode;
uint64_t incident_gen;
fd_t *fd;
fd_t *fd;
} qr_local_t;
qr_inode_t *
qr_inode_ctx_get (xlator_t *this, inode_t *inode);
void
__qr_inode_prune_data (xlator_t *this, qr_inode_table_t *table,
qr_inode_t *qr_inode);
void
qr_local_wipe (qr_local_t *local)
{
@ -38,17 +45,68 @@ out:
return;
}
uint64_t
__qr_get_generation (xlator_t *this, qr_inode_t *qr_inode)
{
uint64_t gen = 0, rollover;
qr_private_t *priv = NULL;
qr_inode_table_t *table = NULL;
priv = this->private;
table = &priv->table;
gen = GF_ATOMIC_INC (priv->generation);
if (gen == 0) {
qr_inode->gen_rollover = !qr_inode->gen_rollover;
gen = GF_ATOMIC_INC (priv->generation);
__qr_inode_prune_data (this, table, qr_inode);
qr_inode->gen = qr_inode->invalidation_time = gen - 1;
}
rollover = qr_inode->gen_rollover;
gen |= (rollover << 32);
return gen;
}
uint64_t
qr_get_generation (xlator_t *this, inode_t *inode)
{
qr_inode_t *qr_inode = NULL;
uint64_t gen = 0;
qr_inode_table_t *table = NULL;
qr_private_t *priv = NULL;
priv = this->private;
table = &priv->table;
qr_inode = qr_inode_ctx_get (this, inode);
if (qr_inode) {
LOCK (&table->lock);
{
gen = __qr_get_generation (this, qr_inode);
}
UNLOCK (&table->lock);
} else {
gen = GF_ATOMIC_INC (priv->generation);
if (gen == 0) {
gen = GF_ATOMIC_INC (priv->generation);
}
}
return gen;
}
qr_local_t *
qr_local_get (xlator_t *this)
qr_local_get (xlator_t *this, inode_t *inode)
{
qr_local_t *local = NULL;
qr_private_t *priv = this->private;
local = GF_CALLOC (1, sizeof (*local), gf_common_mt_char);
if (!local)
goto out;
local->incident_gen = GF_ATOMIC_INC (priv->generation);
local->incident_gen = qr_get_generation (this, inode);
out:
return local;
}
@ -64,7 +122,6 @@ out:
} while (0)
qr_inode_t *qr_inode_ctx_get (xlator_t *this, inode_t *inode);
void __qr_inode_prune (xlator_t *this, qr_inode_table_t *table,
qr_inode_t *qr_inode, uint64_t gen);
@ -105,12 +162,16 @@ qr_inode_ctx_get (xlator_t *this, inode_t *inode)
{
qr_inode_t *qr_inode = NULL;
if (inode == NULL)
goto out;
LOCK (&inode->lock);
{
qr_inode = __qr_inode_ctx_get (this, inode);
}
UNLOCK (&inode->lock);
out:
return qr_inode;
}
@ -239,11 +300,9 @@ qr_inode_set_priority (xlator_t *this, inode_t *inode, const char *path)
UNLOCK (&table->lock);
}
/* To be called with priv->table.lock held */
void
__qr_inode_prune (xlator_t *this, qr_inode_table_t *table, qr_inode_t *qr_inode,
uint64_t gen)
__qr_inode_prune_data (xlator_t *this, qr_inode_table_t *table,
qr_inode_t *qr_inode)
{
qr_private_t *priv = NULL;
@ -252,9 +311,6 @@ __qr_inode_prune (xlator_t *this, qr_inode_table_t *table, qr_inode_t *qr_inode,
GF_FREE (qr_inode->data);
qr_inode->data = NULL;
/* Set gen only with valid callers */
qr_inode->gen = gen;
if (!list_empty (&qr_inode->lru)) {
table->cache_used -= qr_inode->size;
qr_inode->size = 0;
@ -265,7 +321,18 @@ __qr_inode_prune (xlator_t *this, qr_inode_table_t *table, qr_inode_t *qr_inode,
}
memset (&qr_inode->buf, 0, sizeof (qr_inode->buf));
qr_inode->invalidation_time = GF_ATOMIC_INC (priv->generation);
}
/* To be called with priv->table.lock held */
void
__qr_inode_prune (xlator_t *this, qr_inode_table_t *table, qr_inode_t *qr_inode,
uint64_t gen)
{
__qr_inode_prune_data (this, table, qr_inode);
if (gen)
qr_inode->gen = gen;
qr_inode->invalidation_time = __qr_get_generation (this, qr_inode);
}
@ -299,17 +366,13 @@ __qr_cache_prune (xlator_t *this, qr_inode_table_t *table, qr_conf_t *conf)
qr_inode_t *next = NULL;
int index = 0;
size_t size_pruned = 0;
qr_private_t *priv = NULL;
priv = this->private;
for (index = 0; index < conf->max_pri; index++) {
list_for_each_entry_safe (curr, next, &table->lru[index], lru) {
size_pruned += curr->size;
__qr_inode_prune (this, table, curr,
GF_ATOMIC_INC (priv->generation));
__qr_inode_prune (this, table, curr, 0);
if (table->cache_used < conf->cache_size)
return;
@ -367,16 +430,20 @@ void
qr_content_update (xlator_t *this, qr_inode_t *qr_inode, void *data,
struct iatt *buf, uint64_t gen)
{
qr_private_t *priv = NULL;
qr_inode_table_t *table = NULL;
qr_private_t *priv = NULL;
qr_inode_table_t *table = NULL;
uint32_t rollover = 0;
rollover = gen >> 32;
gen = gen & 0xffffffff;
priv = this->private;
table = &priv->table;
LOCK (&table->lock);
{
/* allow for rollover of frame->root->unique */
if (gen && qr_inode->gen && (qr_inode->gen >= gen))
if ((rollover != qr_inode->gen_rollover) ||
(gen && qr_inode->gen && (qr_inode->gen >= gen)))
goto unlock;
if ((qr_inode->data == NULL) &&
@ -450,13 +517,18 @@ __qr_content_refresh (xlator_t *this, qr_inode_t *qr_inode, struct iatt *buf,
qr_private_t *priv = NULL;
qr_inode_table_t *table = NULL;
qr_conf_t *conf = NULL;
uint32_t rollover = 0;
rollover = gen >> 32;
gen = gen & 0xffffffff;
priv = this->private;
table = &priv->table;
conf = &priv->conf;
/* allow for rollover of frame->root->unique */
if (gen && qr_inode->gen && (qr_inode->gen >= gen))
if ((rollover != qr_inode->gen_rollover) ||
(gen && qr_inode->gen && (qr_inode->gen >= gen)))
goto done;
if ((qr_inode->data == NULL) && (qr_inode->invalidation_time >= gen))
@ -591,7 +663,7 @@ qr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
priv = this->private;
conf = &priv->conf;
local = qr_local_get (this);
local = qr_local_get (this, loc->inode);
local->inode = inode_ref (loc->inode);
frame->local = local;
@ -664,7 +736,7 @@ qr_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
{
qr_local_t *local = NULL;
local = qr_local_get (this);
local = qr_local_get (this, NULL);
frame->local = local;
STACK_WIND (frame, qr_readdirp_cbk,
@ -793,7 +865,7 @@ qr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *iov,
{
qr_local_t *local = NULL;
local = qr_local_get (this);
local = qr_local_get (this, fd->inode);
local->fd = fd_ref (fd);
frame->local = local;
@ -826,7 +898,7 @@ qr_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
{
qr_local_t *local = NULL;
local = qr_local_get (this);
local = qr_local_get (this, loc->inode);
local->inode = inode_ref (loc->inode);
frame->local = local;
@ -857,7 +929,7 @@ qr_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
{
qr_local_t *local = NULL;
local = qr_local_get (this);
local = qr_local_get (this, fd->inode);
local->fd = fd_ref (fd);
frame->local = local;
@ -888,7 +960,7 @@ qr_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, int keep_size,
{
qr_local_t *local = NULL;
local = qr_local_get (this);
local = qr_local_get (this, fd->inode);
local->fd = fd_ref (fd);
frame->local = local;
@ -919,7 +991,7 @@ qr_discard (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
{
qr_local_t *local = NULL;
local = qr_local_get (this);
local = qr_local_get (this, fd->inode);
local->fd = fd_ref (fd);
frame->local = local;
@ -950,7 +1022,7 @@ qr_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
{
qr_local_t *local = NULL;
local = qr_local_get (this);
local = qr_local_get (this, fd->inode);
local->fd = fd_ref (fd);
frame->local = local;
@ -976,14 +1048,13 @@ int
qr_forget (xlator_t *this, inode_t *inode)
{
qr_inode_t *qr_inode = NULL;
qr_private_t *priv = this->private;
qr_inode = qr_inode_ctx_get (this, inode);
if (!qr_inode)
return 0;
qr_inode_prune (this, inode, GF_ATOMIC_INC (priv->generation));
qr_inode_prune (this, inode, qr_get_generation (this, inode));
GF_FREE (qr_inode);
@ -1472,7 +1543,7 @@ qr_invalidate (xlator_t *this, void *data)
ret = -1;
goto out;
}
qr_inode_prune (this, inode, GF_ATOMIC_INC (priv->generation));
qr_inode_prune (this, inode, qr_get_generation (this, inode));
}
out:

View File

@ -38,6 +38,7 @@ struct qr_inode {
uint32_t ia_mtime_nsec;
uint32_t ia_ctime;
uint32_t ia_ctime_nsec;
uint32_t gen_rollover;
struct iatt buf;
struct timeval last_refresh;
struct list_head lru;
@ -85,7 +86,7 @@ struct qr_private {
time_t last_child_down;
gf_lock_t lock;
struct qr_statistics qr_counter;
gf_atomic_t generation;
gf_atomic_int32_t generation;
};
typedef struct qr_private qr_private_t;