Improve control and reporting of overprovisioning. Added OP parameter to recipe, and calculation of OP to output spreadsheet. Fixed a bug so now partition size is reported correctly.

This commit is contained in:
Laura Caulfield 2017-05-01 09:47:01 -07:00
Родитель 455cd074d1
Коммит 70aec20831
7 изменённых файлов: 213 добавлений и 37 удалений

Просмотреть файл

@ -2,4 +2,4 @@ The results in this directory were generated from
the version of storscore published on the date listed
below. If there is no date, the results were generated
from an unpublished & untracked version of code.
Tue 01/24/2017 9:00:53.83
Mon 05/01/2017 9:25:23.74

Просмотреть файл

@ -138,11 +138,11 @@ has 'active_range' => (
writer => '_active_range'
);
has 'partition_bytes' => (
has 'partition_bytes_override' => (
is => 'ro',
isa => 'Maybe[Int]',
default => undef,
writer => '_partition_bytes'
writer => '_partition_bytes_override'
);
has 'demo_mode' => (
@ -155,7 +155,7 @@ has 'demo_mode' => (
has 'auto_upload' => (
is => 'ro',
isa => 'Bool',
default => 1,
default => 0,
writer => '_auto_upload'
);
@ -279,7 +279,7 @@ sub BUILD
"io_generator=s" => sub { $self->attr(@_) },
"io_generator_args=s" => sub { $self->attr(@_) },
"active_range=i" => sub { $self->attr(@_) },
"partition_bytes=i" => sub { $self->attr(@_) },
"partition_bytes_override=i" => sub { $self->attr(@_) },
"demo_mode!" => sub { $self->attr(@_) },
"auto_upload!" => sub { $self->attr(@_) },
"results_share=s" => sub { $self->attr(@_) },
@ -349,11 +349,11 @@ END
warn $msg;
}
if( defined $self->partition_bytes )
if( defined $self->partition_bytes_override )
{
my $msg;
$msg .= "Ignoring --partition_bytes. ";
$msg .= "Ignoring --partition_bytes_override. ";
$msg .= "Not supported in raw disk mode.\n";
warn $msg;

Просмотреть файл

@ -54,6 +54,9 @@ sub compute_endurance($)
$stats_ref->{'Rated PE Cycles'} = $ddb_ref->{'Rated PE Cycles'};
compute_internal_capacity( $stats_ref, $ddb_ref );
compute_OP( $stats_ref, $ddb_ref );
return unless test_contains_writes( $stats_ref );
compute_host_writes( $stats_ref, $ddb_ref );
@ -190,21 +193,8 @@ sub compute_dwpd($$)
return unless $waf > 0;
my $internal_capacity = $ddb_ref->{'Internal Capacity'};
my $total_nand_bytes;
# If DeviceDB contains the actual internal capacity, use that.
# Otherwise make a resonable assumption.
if( defined $internal_capacity )
{
$total_nand_bytes = human_to_bytes( $internal_capacity );
}
else
{
$total_nand_bytes =
round_up_power2( $stats_ref->{'User Capacity (B)'} );
}
my $total_nand_bytes = $stats_ref->{'Raw Capacity (GiB)'} *
BYTES_PER_GB_BASE2;
# Give the drive credit for OP and TRIM'd space
my $mapped_bytes = $stats_ref->{'Partition Size (B)'};
@ -227,4 +217,47 @@ sub test_contains_writes($)
return $stats_ref->{'W Mix'} > 0;
}
sub compute_OP($$)
{
my $stats_ref = shift;
my $ddb_ref = shift;
my $exposed_bytes =
$stats_ref->{'Partition Size (GB)'} * BYTES_PER_GB_BASE10;
# NB: it's conventional to interpret the raw capacity in GB instead of
# GiB. This is how a 512GB drive has "0% OP" and can still maintain an FTL.
my $raw_bytes =
$stats_ref->{'Raw Capacity (GiB)'} * BYTES_PER_GB_BASE10;
my $hidden_bytes = $raw_bytes - $exposed_bytes;
$stats_ref->{'Overprovisioning'} =
( $hidden_bytes / $exposed_bytes ) * 100 // "Unavailable";
}
sub compute_internal_capacity($$)
{
my $stats_ref = shift;
my $ddb_ref = shift;
my $internal_capacity = $ddb_ref->{'Internal Capacity'};
my $total_nand_bytes;
# If DeviceDB contains the actual internal capacity, use that.
# Otherwise make a resonable assumption.
if( defined $internal_capacity )
{
$total_nand_bytes = human_to_bytes( $internal_capacity );
}
else
{
$total_nand_bytes =
round_up_power2( $stats_ref->{'User Capacity (B)'} );
}
$stats_ref->{'Raw Capacity (GiB)'} = $total_nand_bytes / BYTES_PER_GB_BASE2;
}
1;

Просмотреть файл

@ -583,7 +583,7 @@ sub get_test_macro_string
$str .= q( purge() if $args{'purge'} // 1; )
if $self->target->do_purge;
$str .= q( initialize() if $args{'initialize'} // 1; )
$str .= q( initialize( %args ) if $args{'initialize'} // 1; )
if $self->target->do_initialize;
$str .= q( precondition( %args ) if $args{'precondition'} // 1; )
@ -694,12 +694,12 @@ sub get_announcement_message
my $short_pattern =
$step_ref->{'access_pattern'} eq "random" ? "rnd" : "seq";
$msg = sprintf( " %4s, %3s, %3d%% read, %3d%% wri, QD=%3d",
$msg = sprintf( " %4s, %3s, %3d%% wri, QD=%3d, Used=%3d%%",
$step_ref->{'block_size'},
$short_pattern,
$step_ref->{'read_percentage'},
$step_ref->{'write_percentage'},
$step_ref->{'queue_depth'}
$step_ref->{'queue_depth'},
$step_ref->{'percent_used'} // 100
);
}
elsif( $step_ref->{'kind'} eq 'idle' )
@ -788,6 +788,7 @@ sub run_step
{
$self->target->initialize(
msg_prefix => $progress,
test_ref => $step_ref
);
}
elsif( $kind eq 'precondition' )
@ -800,7 +801,7 @@ sub run_step
}
elsif( $kind eq 'test' )
{
$self->target->prepare()
$self->target->prepare( $step_ref )
unless $self->target->is_prepared();
unless( $pretend or $self->cmd_line->raw_disk )
@ -810,6 +811,14 @@ sub run_step
}
my $desc = $step_ref->{'description'};
# Record statistics about this volume
my $wmic_runner = WmicRunner->new(
target => $self->target,
output_dir => $self->output_dir
);
$wmic_runner->collect( "wmic-$desc.txt" );
# Record background activity, if any, during this test
if( scalar @{$self->bg_processes} > 0 )
@ -908,7 +917,7 @@ sub run_step
#
# Does this make sense in a general purpose exec (fg & bg)?
$self->target->prepare()
$self->target->prepare( $step_ref )
unless $self->target->is_prepared();
unless( $pretend )

Просмотреть файл

@ -366,17 +366,27 @@ sub purge
$self->_is_prepared( 0 );
}
sub prepare
sub prepare($)
{
my $self = shift;
my $test_ref = shift;
return if $self->is_prepared;
if( $self->do_create_new_filesystem )
{
my $partition_bytes;
$partition_bytes = ( $test_ref->{'percent_used'} / 100.0 ) *
get_drive_size( $self->physical_drive )
if defined $test_ref->{'percent_used'};
$partition_bytes = $self->cmd_line->partition_bytes_override
if defined $self->cmd_line->partition_bytes_override;
create_filesystem(
$self->physical_drive,
$self->cmd_line->partition_bytes
$partition_bytes
);
$self->_volume( physical_drive_to_volume( $self->physical_drive ) );
@ -473,11 +483,7 @@ sub initialize
my $msg_prefix = $args{'msg_prefix'} // die;
my $test_ref = $args{'test_ref'};
if( defined $test_ref )
{
# Future work: allow for custom init pattern
...
}
# Future work: allow for custom init pattern
unless( $self->do_initialize )
{
@ -497,7 +503,7 @@ sub initialize
return;
}
$self->prepare() unless $self->is_prepared();
$self->prepare( $test_ref ) unless $self->is_prepared();
$self->precondition_runner->write_num_passes(
msg_prefix => $msg_prefix . "Initializing: ",
@ -534,7 +540,7 @@ sub precondition
return;
}
$self->prepare() unless $self->is_prepared();
$self->prepare( $test_ref ) unless $self->is_prepared();
$self->precondition_runner->run_to_steady_state(
msg_prefix => $msg_prefix . "Preconditioning: ",

Просмотреть файл

@ -525,6 +525,11 @@ push @cols,
# don't want 3rd parties to see these
push @cols,
(
{ name => 'Raw Capacity (GiB)' },
{
name => 'Overprovisioning',
format => '#.#%',
},
{
name => 'Wear Range Before',
format => '#.#',
@ -682,6 +687,12 @@ sub parse_directories(@)
$file_stats{'Test Description'} = $base_name;
generate_timestamp( $base_name, \%file_stats );
if( -e "wmic-$base_name.txt" )
{
my $wmic = WmicParser->new();
$wmic->parse( \%file_stats, "wmic-$base_name.txt" );
}
parse_warmup_file(
"warmup-$base_name.txt",

117
recipes/specification.rcp Normal file
Просмотреть файл

@ -0,0 +1,117 @@
# vim: set filetype=perl:
# StorScore
#
# Copyright (c) Microsoft Corporation
#
# All rights reserved.
#
# MIT License
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
# These tests correspond to the requirements defined in the WCS SSD
# Specification version 3.0
include 'write_impact_check.rcp';
test(
description => "Random Reads",
write_percentage => 0,
access_pattern => 'random',
block_size => '4K',
queue_depth => 4,
warmup_time => 60,
run_time => 3600,
);
test(
description => "Random Writes",
write_percentage => 100,
access_pattern => 'random',
block_size => '4K',
queue_depth => 32,
warmup_time => 60,
run_time => 3600,
);
test(
description => "Random 4k Mix",
write_percentage => 100,
access_pattern => 'random',
block_size => '4K',
queue_depth => 32,
warmup_time => 60,
run_time => 3600,
);
test(
description => "Random 8k Mix",
write_percentage => 100,
access_pattern => 'random',
block_size => '8K',
queue_depth => 1,
warmup_time => 60,
run_time => 3600,
);
test(
description => "Sequential Reads",
write_percentage => 0,
access_pattern => 'sequential',
block_size => '128K',
queue_depth => 32,
warmup_time => 60,
run_time => 3600,
);
test(
description => "Sequential Writes",
write_percentage => 100,
access_pattern => 'sequential',
block_size => '128K',
queue_depth => 32,
warmup_time => 60,
run_time => 3600,
);
# 20% OP corresponds to 88.89% of user-visible capacity
test(
description => "Random Writes 20% OP",
percent_used => 88.89,
write_percentage => 100,
access_pattern => 'random',
block_size => '4K',
queue_depth => 32,
warmup_time => 60,
run_time => 3600,
);
test(
description => "Random Mix 20% OP",
percent_used => 88.89,
write_percentage => 100,
access_pattern => 'random',
block_size => '8K',
queue_depth => 32,
warmup_time => 60,
run_time => 3600,
);