client->pools[d_poolid] = global_shared_pools[s_poolid];
shared_pool_join(global_shared_pools[s_poolid], client);
pool_free(pool);
- if ( this_cli_id != CLI_ID_NULL )
- tmh_client_put(client->tmh);
return d_poolid;
}
}
}
}
client->pools[d_poolid] = pool;
- if ( this_cli_id != CLI_ID_NULL )
- tmh_client_put(client->tmh);
list_add_tail(&pool->pool_list, &global_pool_list);
pool->pool_id = d_poolid;
pool->persistent = persistent;
fail:
pool_free(pool);
- if ( this_cli_id != CLI_ID_NULL )
- tmh_client_put(client->tmh);
return -EPERM;
}
if ( (client = tmh_client_from_cli_id(cli_id)) == NULL)
return -1;
client_freeze(client,freeze);
- tmh_client_put(client->tmh);
printk("tmem: all pools %s for %s=%d\n",s,cli_id_str,cli_id);
}
return 0;
}
else if ( (client = tmh_client_from_cli_id(cli_id)) == NULL)
return -1;
- else {
+ else
off = tmemc_list_client(client, buf, 0, len, use_long);
- tmh_client_put(client->tmh);
- }
return 0;
}
else if ( (client = tmh_client_from_cli_id(cli_id)) == NULL)
return -1;
else
- {
tmemc_set_var_one(client, subop, arg1);
- tmh_client_put(client->tmh);
- }
return 0;
}
if ( auth == 0 )
client->shared_auth_uuid[i][0] =
client->shared_auth_uuid[i][1] = -1L;
- tmh_client_put(client->tmh);
return 1;
}
if ( (auth == 1) && (client->shared_auth_uuid[i][0] == -1L) &&
free = i;
}
if ( auth == 0 )
- {
- tmh_client_put(client->tmh);
return 0;
- }
if ( auth == 1 && free == -1 )
return -ENOMEM;
client->shared_auth_uuid[free][0] = uuid_lo;
client->shared_auth_uuid[free][1] = uuid_hi;
- tmh_client_put(client->tmh);
return 1;
}
client->frozen = client->was_frozen;
rc = 0;
}
- if ( client )
- tmh_client_put(client->tmh);
return rc;
}
unsigned int pagesize = 1 << (pool->pageshift+12);
if ( pool == NULL || is_ephemeral(pool) )
- {
- tmh_client_put(client->tmh);
return -1;
- }
if ( bufsize < pagesize + sizeof(struct tmem_handle) )
- {
- tmh_client_put(client->tmh);
return -ENOMEM;
- }
tmem_spin_lock(&pers_lists_spinlock);
if ( list_empty(&pool->persistent_page_list) )
out:
tmem_spin_unlock(&pers_lists_spinlock);
- tmh_client_put(client->tmh);
return ret;
}
if ( client == NULL )
return 0;
if ( bufsize < sizeof(struct tmem_handle) )
- {
- tmh_client_put(client->tmh);
return 0;
- }
tmem_spin_lock(&pers_lists_spinlock);
if ( list_empty(&client->persistent_invalidated_list) )
goto out;
ret = 1;
out:
tmem_spin_unlock(&pers_lists_spinlock);
- tmh_client_put(client->tmh);
return ret;
}
client_t *client = tmh_client_from_cli_id(cli_id);
pool_t *pool = (client == NULL || pool_id >= MAX_POOLS_PER_DOMAIN)
? NULL : client->pools[pool_id];
- int rc = pool ? do_tmem_put(pool,oid,index,0,0,0,bufsize,buf.p) : -1;
- if ( client )
- tmh_client_put(client->tmh);
- return rc;
+ if ( pool == NULL )
+ return -1;
+ return do_tmem_put(pool,oid,index,0,0,0,bufsize,buf.p);
}
static int tmemc_restore_flush_page(int cli_id, int pool_id, uint64_t oid,
client_t *client = tmh_client_from_cli_id(cli_id);
pool_t *pool = (client == NULL || pool_id >= MAX_POOLS_PER_DOMAIN)
? NULL : client->pools[pool_id];
- int rc = pool ? do_tmem_flush_page(pool, oid, index) : -1;
- if ( client )
- tmh_client_put(client->tmh);
- return rc;
+ if ( pool == NULL )
+ return -1;
+ return do_tmem_flush_page(pool,oid,index);
}
static NOINLINE int do_tmem_control(struct tmem_op *op)
extern tmh_client_t *tmh_client_init(cli_id_t);
extern void tmh_client_destroy(tmh_client_t *);
-/* this appears to be unreliable when a domain is being shut down */
+/* we don't need to take a reference to the domain here as we hold
+ * one for the entire life of the client, so use rcu_lock_domain_by_id
+ * variant instead of get_domain_by_id() */
static inline struct client *tmh_client_from_cli_id(cli_id_t cli_id)
{
- struct domain *d = get_domain_by_id(cli_id); /* incs d->refcnt! */
+ struct client *c;
+ struct domain *d = rcu_lock_domain_by_id(cli_id);
if (d == NULL)
return NULL;
- return (struct client *)(d->tmem);
-}
-
-static inline void tmh_client_put(tmh_client_t *tmh)
-{
- put_domain(tmh->domain);
+ c = (struct client *)(d->tmem);
+ rcu_unlock_domain(d);
+ return c;
}
static inline struct client *tmh_client_from_current(void)
static inline void tmh_set_client_from_id(struct client *client,
tmh_client_t *tmh, cli_id_t cli_id)
{
+ /* here we DO want to take/hold a reference to the domain as
+ * this routine should be called exactly once when the client is created;
+ * the matching put_domain is in tmh_client_destroy */
struct domain *d = get_domain_by_id(cli_id);
d->tmem = client;
tmh->domain = d;