Merge branch 'linux-zpios' into refs/top-bases/linux-zfs-branch

This commit is contained in:
Brian Behlendorf 2009-07-21 10:35:24 -07:00
commit 6af0c921a6
3 changed files with 142 additions and 78 deletions

View File

@ -131,13 +131,6 @@ print_flags(char *str, uint32_t flags)
return str;
}
static double
timespec_to_double(struct timespec t)
{
return ((double)(t.tv_sec) +
((double)(t.tv_nsec) / (double)(1000*1000*1000)));
}
static int
regex_match(const char *string, char *pattern)
{
@ -352,11 +345,11 @@ print_stats_human_readable(cmd_args_t *args, zpios_cmd_t *cmd)
}
summary_stats = (zpios_stats_t *)cmd->cmd_data_str;
t_time = timespec_to_double(summary_stats->total_time.delta);
wr_time = timespec_to_double(summary_stats->wr_time.delta);
rd_time = timespec_to_double(summary_stats->rd_time.delta);
cr_time = timespec_to_double(summary_stats->cr_time.delta);
rm_time = timespec_to_double(summary_stats->rm_time.delta);
t_time = zpios_timespec_to_double(summary_stats->total_time.delta);
wr_time = zpios_timespec_to_double(summary_stats->wr_time.delta);
rd_time = zpios_timespec_to_double(summary_stats->rd_time.delta);
cr_time = zpios_timespec_to_double(summary_stats->cr_time.delta);
rm_time = zpios_timespec_to_double(summary_stats->rm_time.delta);
printf("%.2f\t", t_time);
printf("%.3f\t", cr_time);
@ -402,24 +395,24 @@ print_stats_table(cmd_args_t *args, zpios_cmd_t *cmd)
}
summary_stats = (zpios_stats_t *)cmd->cmd_data_str;
wr_time = timespec_to_double(summary_stats->wr_time.delta);
rd_time = timespec_to_double(summary_stats->rd_time.delta);
wr_time = zpios_timespec_to_double(summary_stats->wr_time.delta);
rd_time = zpios_timespec_to_double(summary_stats->rd_time.delta);
printf("%ld.%02ld\t",
summary_stats->total_time.delta.tv_sec,
summary_stats->total_time.delta.tv_nsec);
(long)summary_stats->total_time.delta.ts_sec,
(long)summary_stats->total_time.delta.ts_nsec);
printf("%ld.%02ld\t",
summary_stats->cr_time.delta.tv_sec,
summary_stats->cr_time.delta.tv_nsec);
(long)summary_stats->cr_time.delta.ts_sec,
(long)summary_stats->cr_time.delta.ts_nsec);
printf("%ld.%02ld\t",
summary_stats->rm_time.delta.tv_sec,
summary_stats->rm_time.delta.tv_nsec);
(long)summary_stats->rm_time.delta.ts_sec,
(long)summary_stats->rm_time.delta.ts_nsec);
printf("%ld.%02ld\t",
summary_stats->wr_time.delta.tv_sec,
summary_stats->wr_time.delta.tv_nsec);
(long)summary_stats->wr_time.delta.ts_sec,
(long)summary_stats->wr_time.delta.ts_nsec);
printf("%ld.%02ld\t",
summary_stats->rd_time.delta.tv_sec,
summary_stats->rd_time.delta.tv_nsec);
(long)summary_stats->rd_time.delta.ts_sec,
(long)summary_stats->rd_time.delta.ts_nsec);
printf("%lld\t", (long long unsigned)summary_stats->wr_data);
printf("%lld\t", (long long unsigned)summary_stats->wr_chunks);

View File

@ -78,10 +78,15 @@ typedef struct zpios_cfg {
int32_t cfg_rc1; /* Config response 1 */
} zpios_cfg_t;
typedef struct zpios_timespec {
uint32_t ts_sec;
uint32_t ts_nsec;
} zpios_timespec_t;
typedef struct zpios_time {
struct timespec start;
struct timespec stop;
struct timespec delta;
zpios_timespec_t start;
zpios_timespec_t stop;
zpios_timespec_t delta;
} zpios_time_t;
typedef struct zpios_stats {
@ -118,11 +123,74 @@ typedef struct zpios_cmd {
} zpios_cmd_t;
/* Valid ioctls */
#define ZPIOS_CFG _IOWR('f', 101, long)
#define ZPIOS_CMD _IOWR('f', 102, long)
#define ZPIOS_CFG _IOWR('f', 101, zpios_cfg_t)
#define ZPIOS_CMD _IOWR('f', 102, zpios_cmd_t)
/* Valid configuration commands */
#define ZPIOS_CFG_BUFFER_CLEAR 0x001 /* Clear text buffer */
#define ZPIOS_CFG_BUFFER_SIZE 0x002 /* Resize text buffer */
#ifndef NSEC_PER_SEC
#define NSEC_PER_SEC 1000000000L
#endif
static inline
void zpios_timespec_normalize(zpios_timespec_t *ts, uint32_t sec, uint32_t nsec)
{
while (nsec >= NSEC_PER_SEC) {
nsec -= NSEC_PER_SEC;
sec++;
}
while (nsec < 0) {
nsec += NSEC_PER_SEC;
sec--;
}
ts->ts_sec = sec;
ts->ts_nsec = nsec;
}
static inline
zpios_timespec_t zpios_timespec_add(zpios_timespec_t lhs, zpios_timespec_t rhs)
{
zpios_timespec_t ts_delta;
zpios_timespec_normalize(&ts_delta, lhs.ts_sec + rhs.ts_sec,
lhs.ts_nsec + rhs.ts_nsec);
return ts_delta;
}
static inline
zpios_timespec_t zpios_timespec_sub(zpios_timespec_t lhs, zpios_timespec_t rhs)
{
zpios_timespec_t ts_delta;
zpios_timespec_normalize(&ts_delta, lhs.ts_sec - rhs.ts_sec,
lhs.ts_nsec - rhs.ts_nsec);
return ts_delta;
}
#ifdef _KERNEL
static inline
zpios_timespec_t zpios_timespec_now(void)
{
zpios_timespec_t zts_now;
struct timespec ts_now;
ts_now = current_kernel_time();
zts_now.ts_sec = ts_now.tv_sec;
zts_now.ts_nsec = ts_now.tv_nsec;
return zts_now;
}
#else
static inline
double zpios_timespec_to_double(zpios_timespec_t ts)
{
return ((double)(ts.ts_sec) +
((double)(ts.ts_nsec) / (double)(NSEC_PER_SEC)));
}
#endif /* _KERNEL */
#endif /* _ZPIOS_CTL_H */

View File

@ -43,15 +43,6 @@
static struct class *zpios_class;
static inline
struct timespec timespec_add(struct timespec lhs, struct timespec rhs)
{
struct timespec ts_delta;
set_normalized_timespec(&ts_delta, lhs.tv_sec + rhs.tv_sec,
lhs.tv_nsec + rhs.tv_nsec);
return ts_delta;
}
static
int zpios_upcall(char *path, char *phase, run_args_t *run_args, int rc)
{
@ -175,7 +166,7 @@ zpios_dmu_setup(run_args_t *run_args)
int i, rc = 0;
(void)zpios_upcall(run_args->pre, PHASE_PRE_CREATE, run_args, 0);
t->start = current_kernel_time();
t->start = zpios_timespec_now();
rc = dmu_objset_open(run_args->pool, DMU_OST_ZFS, DS_MODE_USER, &os);
if (rc) {
@ -224,8 +215,8 @@ zpios_dmu_setup(run_args_t *run_args)
run_args->os = os;
out:
t->stop = current_kernel_time();
t->delta = timespec_sub(t->stop, t->start);
t->stop = zpios_timespec_now();
t->delta = zpios_timespec_sub(t->stop, t->start);
(void)zpios_upcall(run_args->post, PHASE_POST_CREATE, run_args, rc);
return rc;
@ -320,9 +311,9 @@ zpios_get_work_item(run_args_t *run_args, dmu_obj_t *obj, __u64 *offset,
i++;
count++;
if (unlikely(rw_time->stop.tv_sec == 0) &&
unlikely(rw_time->stop.tv_nsec == 0))
rw_time->stop = current_kernel_time();
if (unlikely(rw_time->stop.ts_sec == 0) &&
unlikely(rw_time->stop.ts_nsec == 0))
rw_time->stop = zpios_timespec_now();
continue;
}
@ -357,7 +348,7 @@ zpios_remove_objects(run_args_t *run_args)
int rc = 0, i;
(void)zpios_upcall(run_args->pre, PHASE_PRE_REMOVE, run_args, 0);
t->start = current_kernel_time();
t->start = zpios_timespec_now();
if (run_args->flags & DMU_REMOVE) {
if (run_args->flags & DMU_FPP) {
@ -385,8 +376,8 @@ zpios_remove_objects(run_args_t *run_args)
dmu_objset_close(run_args->os);
t->stop = current_kernel_time();
t->delta = timespec_sub(t->stop, t->start);
t->stop = zpios_timespec_now();
t->delta = zpios_timespec_sub(t->stop, t->start);
(void)zpios_upcall(run_args->post, PHASE_POST_REMOVE, run_args, rc);
}
@ -514,7 +505,7 @@ zpios_thread_main(void *data)
/* Write phase */
mutex_enter(&thr->lock);
thr->stats.wr_time.start = current_kernel_time();
thr->stats.wr_time.start = zpios_timespec_now();
mutex_exit(&thr->lock);
while (zpios_get_work_item(run_args, &obj, &offset,
@ -526,11 +517,11 @@ zpios_thread_main(void *data)
schedule_timeout(thread_delay_tmp); /* In jiffies */
}
t.start = current_kernel_time();
t.start = zpios_timespec_now();
rc = zpios_dmu_write(run_args, obj.os, obj.obj,
offset, chunk_size, buf);
t.stop = current_kernel_time();
t.delta = timespec_sub(t.stop, t.start);
t.stop = zpios_timespec_now();
t.delta = zpios_timespec_sub(t.stop, t.start);
if (rc) {
zpios_print(run_args->file, "IO error while doing "
@ -541,14 +532,14 @@ zpios_thread_main(void *data)
mutex_enter(&thr->lock);
thr->stats.wr_data += chunk_size;
thr->stats.wr_chunks++;
thr->stats.wr_time.delta = timespec_add(
thr->stats.wr_time.delta = zpios_timespec_add(
thr->stats.wr_time.delta, t.delta);
mutex_exit(&thr->lock);
mutex_enter(&region->lock);
region->stats.wr_data += chunk_size;
region->stats.wr_chunks++;
region->stats.wr_time.delta = timespec_add(
region->stats.wr_time.delta = zpios_timespec_add(
region->stats.wr_time.delta, t.delta);
/* First time region was accessed */
@ -564,7 +555,7 @@ zpios_thread_main(void *data)
mutex_enter(&thr->lock);
thr->rc = rc;
thr->stats.wr_time.stop = current_kernel_time();
thr->stats.wr_time.stop = zpios_timespec_now();
mutex_exit(&thr->lock);
wake_up(&run_args->waitq);
@ -580,7 +571,7 @@ zpios_thread_main(void *data)
/* Read phase */
mutex_enter(&thr->lock);
thr->stats.rd_time.start = current_kernel_time();
thr->stats.rd_time.start = zpios_timespec_now();
mutex_exit(&thr->lock);
while (zpios_get_work_item(run_args, &obj, &offset,
@ -595,11 +586,11 @@ zpios_thread_main(void *data)
if (run_args->flags & DMU_VERIFY)
memset(buf, 0, chunk_size);
t.start = current_kernel_time();
t.start = zpios_timespec_now();
rc = zpios_dmu_read(run_args, obj.os, obj.obj,
offset, chunk_size, buf);
t.stop = current_kernel_time();
t.delta = timespec_sub(t.stop, t.start);
t.stop = zpios_timespec_now();
t.delta = zpios_timespec_sub(t.stop, t.start);
if (rc) {
zpios_print(run_args->file, "IO error while doing "
@ -623,14 +614,14 @@ zpios_thread_main(void *data)
mutex_enter(&thr->lock);
thr->stats.rd_data += chunk_size;
thr->stats.rd_chunks++;
thr->stats.rd_time.delta = timespec_add(
thr->stats.rd_time.delta = zpios_timespec_add(
thr->stats.rd_time.delta, t.delta);
mutex_exit(&thr->lock);
mutex_enter(&region->lock);
region->stats.rd_data += chunk_size;
region->stats.rd_chunks++;
region->stats.rd_time.delta = timespec_add(
region->stats.rd_time.delta = zpios_timespec_add(
region->stats.rd_time.delta, t.delta);
/* First time region was accessed */
@ -646,7 +637,7 @@ zpios_thread_main(void *data)
mutex_enter(&thr->lock);
thr->rc = rc;
thr->stats.rd_time.stop = current_kernel_time();
thr->stats.rd_time.stop = zpios_timespec_now();
mutex_exit(&thr->lock);
wake_up(&run_args->waitq);
@ -713,7 +704,7 @@ zpios_threads_run(run_args_t *run_args)
tsks[i] = tsk;
}
tt->start = current_kernel_time();
tt->start = zpios_timespec_now();
/* Wake up all threads for write phase */
(void)zpios_upcall(run_args->pre, PHASE_PRE_WRITE, run_args, 0);
@ -721,9 +712,9 @@ zpios_threads_run(run_args_t *run_args)
wake_up_process(tsks[i]);
/* Wait for write phase to complete */
tw->start = current_kernel_time();
tw->start = zpios_timespec_now();
wait_event(run_args->waitq, zpios_thread_done(run_args));
tw->stop = current_kernel_time();
tw->stop = zpios_timespec_now();
(void)zpios_upcall(run_args->post, PHASE_POST_WRITE, run_args, rc);
for (i = 0; i < tc; i++) {
@ -762,9 +753,9 @@ zpios_threads_run(run_args_t *run_args)
wake_up_process(tsks[i]);
/* Wait for read phase to complete */
tr->start = current_kernel_time();
tr->start = zpios_timespec_now();
wait_event(run_args->waitq, zpios_thread_done(run_args));
tr->stop = current_kernel_time();
tr->stop = zpios_timespec_now();
(void)zpios_upcall(run_args->post, PHASE_POST_READ, run_args, rc);
for (i = 0; i < tc; i++) {
@ -780,10 +771,10 @@ zpios_threads_run(run_args_t *run_args)
mutex_exit(&thr->lock);
}
out:
tt->stop = current_kernel_time();
tt->delta = timespec_sub(tt->stop, tt->start);
tw->delta = timespec_sub(tw->stop, tw->start);
tr->delta = timespec_sub(tr->stop, tr->start);
tt->stop = zpios_timespec_now();
tt->delta = zpios_timespec_sub(tt->stop, tt->start);
tw->delta = zpios_timespec_sub(tw->stop, tw->start);
tr->delta = zpios_timespec_sub(tr->stop, tr->start);
cleanup:
kmem_free(tsks, sizeof(struct task_struct *) * tc);
@ -1082,7 +1073,7 @@ static int
zpios_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
unsigned int minor = iminor(file->f_dentry->d_inode);
unsigned int minor = iminor(inode);
int rc = 0;
/* Ignore tty ioctls */
@ -1108,6 +1099,15 @@ zpios_ioctl(struct inode *inode, struct file *file,
return rc;
}
#ifdef CONFIG_COMPAT
/* Compatibility handler for ioctls from 32-bit ELF binaries */
static long
zpios_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
return zpios_ioctl(file->f_dentry->d_inode, file, cmd, arg);
}
#endif /* CONFIG_COMPAT */
/* I'm not sure why you would want to write in to this buffer from
* user space since its principle use is to pass test status info
* back to the user space, but I don't see any reason to prevent it.
@ -1223,13 +1223,16 @@ static loff_t zpios_seek(struct file *file, loff_t offset, int origin)
}
static struct file_operations zpios_fops = {
.owner = THIS_MODULE,
.open = zpios_open,
.release = zpios_release,
.ioctl = zpios_ioctl,
.read = zpios_read,
.write = zpios_write,
.llseek = zpios_seek,
.owner = THIS_MODULE,
.open = zpios_open,
.release = zpios_release,
.ioctl = zpios_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = zpios_compat_ioctl,
#endif
.read = zpios_read,
.write = zpios_write,
.llseek = zpios_seek,
};
static struct cdev zpios_cdev = {