sd_tdaemon.c revision fcf3ce441efd61da9bb2884968af01cb7c1452cc
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Routines for the Infinity Storage Device daemon
*/
#include <sys/nsc_thread.h>
#include "sd_bcache.h"
#include "sd_io.h"
#include "sd_bio.h"
#include "sd_ft.h"
#include "sd_misc.h"
#define _INFSD_LOCAL_MEM
#define SIZEMASK 0x0000FFFF
#define MAX_CD_STS 600
#define MAX_TDAEMONS 128
/*
* sd_test options
*/
#define SD_TEST_CACHE_HIT 0x00000001
#define SD_TEST_CACHE_MISS 0x00000002
#define SD_TEST_CHECK_DATA 0x00000004
#define SD_TEST_READ_ONLY 0x00000008
#define SD_TEST_WRITE_ONLY 0x00000010
#define SD_TEST_SEQUENTIAL 0x00000020
static struct cd_sts {
volatile short cd_state;
volatile char waiting;
volatile char inited;
static kmutex_t tdaemon_lock;
static kcondvar_t _wait_daemons;
static volatile int test_stop;
static int daemon_awake(int i);
static void wakeup_all_tdaemons(void);
static void _sd_idle_daemon(void);
static void _td_detach_cd(int cd);
static void set_parameters(void);
int error);
int
{
int rval;
if (test_stop)
return (EINVAL);
}
static int
int flag)
{
int rval;
}
#define _sd_allocate_buf _trk_allocate_buf
#define _sd_write _sim_write
/*
* INF SD daemon global data
*/
volatile int test_created;
static int _sd_daemon_created;
static int _sd_num_daemons;
static struct gld {
volatile int type;
volatile int loop;
volatile int seed;
volatile int asleep;
} gld[MAX_TDAEMONS];
/*
* _sdbc_tdaemon_load: cache is being loaded, initialize any global state that
*/
int
_sdbc_tdaemon_load(void)
{
int i;
for (i = 0; i < MAX_TDAEMONS; i++)
return (0);
}
/*
* _sdbc_tdaemon_unload: cache is being unloaded.
*/
void
_sdbc_tdaemon_unload(void)
{
int i;
for (i = 0; i < MAX_TDAEMONS; i++) {
}
}
/*
* _sdbc_tdaemon_configure: configure the desired number of test daemons.
*/
int
{
int i;
if (num >= MAX_TDAEMONS)
return (-1);
for (i = 0; i < num; i++) {
}
test_created = 1;
test_stop = 0;
_sd_num_daemons = 0;
if (_sd_daemon_created == 1) {
return (-1);
}
_sd_daemon_created = 1;
for (i = 0; i < num; i++) {
(void) nsc_create_process(
(void (*)(void *))_sd_idle_daemon, 0, FALSE);
}
#ifdef DEBUG
if (num)
#endif
return (0);
}
void
{
if (_sd_num_daemons) {
_sd_daemon_created = 0;
test_created = 0;
test_stop = 1;
while (retry--) {
running = 0;
for (i = 0; i < _sd_num_daemons; i++)
if (daemon_awake(i))
running++;
if (running == 0) break;
}
}
for (i = 0; i < MAX_CD_STS; i++) {
cd_test_sts[i].inited = 0;
}
_sd_num_daemons = 0;
}
int sind = 0;
/*
* Globals to change test parameters - Initially added for tests written
* by Ajay
*/
#ifdef SD_TDAEMON_DEBUG
struct statis {
int cd;
int type;
} statis[4000];
int
{
return (sind);
}
#endif /* SD_TDAEMON_DEBUG */
static int
daemon_awake(int i)
{
return (1);
return (0);
}
static int
daemon_nexist(int i)
{
return (1);
return (0);
}
static void
daemon_wakeup(int i)
{
#ifdef _SD_DEBUG
#endif
}
static void
wakeup_all_tdaemons(void)
{
int i;
for (i = 0; i < _sd_num_daemons; i++)
daemon_wakeup(i);
}
static void
_sd_idle_daemon(void)
{
int who; /* id of this daemon */
who = _sd_num_daemons++;
/* CONSTCOND */
while (1) {
#ifdef DEBUG
#endif
if (test_created == 0) {
return;
} else {
}
_sd_print(0, "%d daemon awake type %d loop %d seed %d",
if (test_created == 0) {
return;
}
case 210:
break;
case 323:
break;
case 350:
1);
break;
case 351:
0);
break;
#if 0
case 400:
break;
#endif
default:
break;
}
if (test_created == 0) {
return;
}
}
}
static void
_td_attach_cd(int cd)
{
}
static void
_td_detach_cd(int cd)
{
}
int
{
register struct a {
long num;
long type;
long loop;
long from;
long seed;
return (0);
}
static int
/*
* test_control - perform control operations outside of the range
*/
{
int rc = 0;
return (-1);
switch (typ) {
case 1:
break;
case 2:
break;
case 3:
cd);
break;
case 4:
_test_async_fail = 0;
break;
#if 0
case 5:
break;
case 6:
_trk_alloc_flag = 0;
break;
#endif
case 7:
break;
case 8:
fba_len);
break;
default:
}
return (rc);
}
/*
* _fork_sd_daemon(): Fork an nunix process that periodically flushes the
* raw device buffer cache
*/
static int
{
int i;
int type;
if (num_disks == -1) {
}
if (type == 100) {
test_stop = 1;
return (0);
}
if (type == 99) {
/* Set some parameters for other tests */
switch (num_disks) {
/* Params set for this test */
#if 0
case 302 :
break;
case 303 :
break;
case 304 :
_sd_trk_size = from;
break;
case 305 :
_sd_max_blks = from;
break;
#endif
default :
"Usage : sd_test <test_num> 99"
" <param1> <param2> <param3>");
break;
}
return (0);
} /* type == 99 */
if (type > 1000) {
dowait = 1;
type -= 1000;
}
if (type > 1000) {
verify = 1;
type -= 1000;
}
if (daemon_awake(i)) {
return (-1);
}
if (daemon_nexist(i)) {
return (-1);
}
daemon_wakeup(i);
}
if (num_disks <= 0)
return (0);
if (dowait) {
wait:
test_stop = 1;
return (-1); /* interrupt */
}
/* wait for all to stop */
if (test_stop)
return (-1);
if (daemon_awake(i))
goto wait;
}
}
if (verify) {
verify = 0;
type++; /* next test */
goto again;
}
return (0);
}
int
_sd_test_end(void)
{
test_created = 0;
test_stop = 1;
return (0);
}
int
_sd_test_init(void *args)
{
register struct a {
long ar;
long len;
long tsize;
long flag;
return (EFAULT);
}
return (0);
}
typedef struct io_type {
char test_pattern;
} infnsc_io_t;
/* static spinlock_t INFSD_iolock = { SLK_IFS_SRVR, 0 }; */
/*
* _sd_test_rwloop_seq(i,loops, seed, forw):
*
* Sequential I/O test. Writes track records sequentially, either forwards
* or backwards (forw = 1 or forw = 0), writing a fixed pattern with a
* few unique bytes depending on loop id. Then reads back, checking
* for data consistency.
*/
/* ARGSUSED */
static void
{
int cd;
int j, len;
int sts;
return;
}
return;
}
SET_CD_STATE(cd, i);
len = 120;
/*
* Write a base pattern into the first buffer
*/
offset = 0;
&fbuf);
if (sts > 0) {
return;
}
offset = 0;
for (j = 0; j < loops; j++) {
break;
if (sts > 0) {
goto done;
}
while (sts > 0) {
12, 0) > 0) {
test_stop = 1;
}
sts -= 12;
test_stop = 1;
}
}
goto done;
}
}
offset = 0;
for (j = 0; j < loops; j++) {
break;
if (sts > 0) {
goto done;
}
goto done;
}
}
done:
}
static int
{
int i;
end_cblk_len = 0;
} else
i)) = nsc_usec();
for (i = 0; i < CACHE_BLOCK_SIZE; i += 4) {
}
cur_fba_len -= BLK_FBAS;
}
if (cur_fba_len) {
}
}
return (0);
}
static int
int skew)
{
unsigned char *skew_word;
int skew_count = 0;
return (0);
}
end_cblk_len = 0;
} else
cur_fba_len -= BLK_FBAS;
}
if (cur_fba_len) {
}
return (0);
}
static int
{
unsigned char *skew_word;
int skew_count = 0;
return (0);
}
end_cblk_len = 0;
} else
FBA_SIZE(st_cblk_len)) != 0)
CACHE_BLOCK_SIZE) != 0)
fba_pos2);
cur_fba_len -= BLK_FBAS;
}
if (cur_fba_len) {
FBA_SIZE(end_cblk_len)) != 0)
fba_pos2);
}
return (0);
}
/*
* Macro definition for waiting for an IO buffer to be allocated or a read
* to complete. Macro defined so code doesn't have to be typed each time
*/
if (st != NSC_PENDING) \
else { \
if (st) { \
if (buf) \
(void) _sd_free_buf(buf); \
return; \
} \
} \
}
/* ARGSUSED */
static void
{
if (error)
tioerr++;
else tiodone++;
}
static int ckd_sskip = 3;
/* ARGSUSED3 */
static void
{
int loops;
int cd;
int done_size;
int i;
int print_stuff;
int throttle;
iosent = 0;
print_stuff = 0;
done_size = 0;
tiodone = 0;
curpos = 0;
tioerr = 0;
return;
}
return;
}
"Test 100: %d recsize %d recs %d throttle %d hd %d doz\n",
for (i = 0; i < loops; i++) {
curpos = i * 120;
if (ckd_doz) {
(void) sd_start_io(bp,
iosent++;
}
if (ckd_doz == 2) {
(void) sd_start_io(bp,
iosent++;
}
(void) sd_start_io(bp,
iosent++;
print_stuff++;
}
;
}
print_stuff++;
}
}
print_stuff++;
}
static void
set_parameters(void)
{
test_stop = 0;
}
static int
init_dmatest(void)
{
if (!dma_mem) {
return (1);
}
return (0);
}
/*ARGSUSED*/
static void
release_dmatest(void)
{
}
/*ARGSUSED*/
static void
{
if (!dma_mem && init_dmatest()) {
return;
}
/*
* The body of test loop is removed since we don't use any more
*/
}