//int create_res_hndl_afu_reset(char *dev, dev64_t devno, __u64 chunk) int create_res_hndl_afu_reset(bool do_recover, bool last) { int rc; struct ctx my_ctx; struct ctx *p_ctx = &my_ctx; //int i; pthread_t thread; __u64 chunk = 0x1; __u64 stride= 0x1; int msgid; struct mymsgbuf msg_buf; pthread_t ioThreadId; do_io_thread_arg_t ioThreadData; do_io_thread_arg_t * p_ioThreadData=&ioThreadData; // we have to export "NO_IO; if we want to avoid IO char * noIOP = getenv("NO_IO"); pid = getpid(); #ifdef _AIX memset(p_ctx,0,sizeof(my_ctx)); strcpy(p_ctx->dev,cflash_path); if ((p_ctx->fd = open_dev(p_ctx->dev, O_RDWR)) < 0) { fprintf(stderr,"open failed %s, errno %d\n",p_ctx->dev, errno); return -1; } rc = ioctl_dk_capi_query_path(p_ctx); CHECK_RC(rc, "ioctl_dk_capi_query_path failed...\n"); rc = ctx_init_internal(p_ctx, 0, p_ctx->devno); #else rc = ctx_init(p_ctx); #endif CHECK_RC(rc, "Context init failed"); //thread to handle AFU interrupt & events if ( noIOP == NULL ) pthread_create(&thread, NULL, ctx_rrq_rx, p_ctx); //create 0 vlun size & later call resize ioctl rc = create_resource(p_ctx, chunk * (p_ctx->chunk_size), 0, LUN_VIRTUAL); CHECK_RC(rc, "create LUN_VIRTUAL failed"); //last new process send message to waiting process //that new ctx created now you can try to reattach msgid = msgget(key, IPC_CREAT | 0666); if (msgid < 0 ) { fprintf(stderr, "%d: msgget() failed before msgsnd()\n", pid); return -1; } memset(&msg_buf, 0, sizeof(struct mymsgbuf)); if (last) { goto end; } if ( noIOP == NULL ) { p_ioThreadData->p_ctx=p_ctx; p_ioThreadData->stride=stride; p_ioThreadData->loopCount=0x100000; // Need this to go on 10 secs debug("%d: things look good, doing IO...\n",pid); rc =pthread_create(&ioThreadId,NULL, do_io_thread, (void *)p_ioThreadData); CHECK_RC(rc, "do_io_thread() pthread_create failed"); } #ifdef _AIX rc = do_eeh(p_ctx); #else rc = do_poll_eeh(p_ctx); #endif g_error=0; //reset any prev error might caught while EEH if ( noIOP == NULL ) { pthread_join(ioThreadId, NULL); } #ifndef _AIX //for linux if ( noIOP == NULL ) pthread_cancel(thread); #endif //We here after EEH done if (do_recover) { //do if recover true debug("%d: woow EEH is done recovering...\n",pid); rc = ioctl_dk_capi_recover_ctx(p_ctx); CHECK_RC(rc, "ctx reattached failed"); msg_buf.mtype =2; strcpy(msg_buf.mtext, "K"); if (msgsnd(msgid, &msg_buf, 2, IPC_NOWAIT) < 0) { fprintf(stderr, "%d: msgsnd failed\n", pid); return -1; } #ifdef _AIX if (p_ctx->return_flags != DK_RF_REATTACHED) CHECK_RC(1, "recover ctx, expected DK_RF_REATTACHED"); p_ctx->flags = DK_VF_HC_TUR; p_ctx->hint = DK_HINT_SENSE; #endif fflush(stdout); ctx_reinit(p_ctx); #ifdef _AIX p_ctx->hint=DK_HINT_SENSE; #else p_ctx->hint=DK_CXLFLASH_VERIFY_HINT_SENSE; // if dummy_sense_flag is set; // a dummy sense data will be copied into ioctl input p_ctx->dummy_sense_flag=1; // if dummy_sense_flag is set; #endif rc = ioctl_dk_capi_verify(p_ctx); CHECK_RC(rc, "ioctl_dk_capi_verify failed"); #ifndef _AIX //for linux pthread_create(&thread, NULL, ctx_rrq_rx, p_ctx); #endif } else { //last one is /*msgid = msgget(key, IPC_CREAT | 0666); if(msgid < 0 ){ fprintf(stderr, "%d: msgget() failed before msgrcv()\n", pid); return -1; } debug("%d: Going to wait at msgrcv()..\n", pid); fflush(stdout); if(msgrcv(msgid, &msg_buf, 2, 1, 0) < 0) { fprintf(stderr, "%d: msgrcv failed with errno %d\n", pid, errno); return -1; } debug("%d: Got out of msgrcv()..EEH is done, Try to recover....\n",pid); */ //as per today(9/28/2015) discussion with Sanket that //new attach will fail until holding context not exited //hope same apply for Linux as well return 100; /*rc = ioctl_dk_capi_recover_ctx(p_ctx); if(rc) return 100; //this to make sure recover failed else { fprintf(stderr,"%d:com'on recover should fail here...\n",pid); return 1; // we don't want to try IO anyway }*/ } end: if ( noIOP == NULL ) { stride=0x1; rc = do_io(p_ctx, stride); CHECK_RC(rc, "IO failed after EEH/recover"); } if ( noIOP == NULL ) pthread_cancel(thread); sleep(1); fflush(stdout); sleep(5); // additional time to be safe ! rc=close_res(p_ctx); sleep(5); // Don't let child exit to keep max ctx alive rc |= ctx_close(p_ctx); CHECK_RC(rc,"ctx close or close_res failed\n"); return rc; }
// 7.1.185 : EEH while super-pipe IO(VIRTUAL)(root user) int test_vSpio_eehRecovery(int cmd) { int rc; struct ctx myctx; struct ctx *p_ctx = &myctx; pthread_t threadId, ioThreadId, thread2; do_io_thread_arg_t ioThreadData; do_io_thread_arg_t * p_ioThreadData=&ioThreadData; __u64 chunk; __u64 nlba; __u64 stride= 0x1000; __u64 last_lba; // pid used to create unique data patterns & logging from util ! pid = getpid(); //ctx_init with default flash disk & devno rc = ctx_init(p_ctx); CHECK_RC(rc, "Context init failed"); //thread to handle AFU interrupt & events rc = pthread_create(&threadId, NULL, ctx_rrq_rx, p_ctx); CHECK_RC(rc, "pthread_create failed"); chunk = (p_ctx->last_phys_lba+1)/p_ctx->chunk_size; nlba = chunk * p_ctx->chunk_size; //create vlun rc = create_resource(p_ctx, nlba, DK_UVF_ALL_PATHS, LUN_VIRTUAL); CHECK_RC(rc, "create LUN_VIRTUAL failed"); // We wish to do IO in a different thread... Setting up for that ! p_ioThreadData->p_ctx=p_ctx; p_ioThreadData->stride=stride; p_ioThreadData->loopCount=1000; rc = pthread_create(&ioThreadId,NULL, do_io_thread, (void *)p_ioThreadData); CHECK_RC(rc, "do_io_thread() pthread_create failed"); //Trigger EEH rc = do_eeh(p_ctx); CHECK_RC(rc, "do_eeh() failed"); // Wait for IO thread to complete pthread_join(ioThreadId, NULL); #ifndef _AIX pthread_cancel(threadId); #endif // Heading for context recovery using ioctl ! //p_ctx->flags = DK_CAPI_REATTACHED; rc = ioctl_dk_capi_recover_ctx(p_ctx); CHECK_RC(rc, "ioctl_dk_capi_recover_ctx failed"); #ifdef _AIX if ( DK_RF_REATTACHED != p_ctx->return_flags ) #else if ( DK_CXLFLASH_RECOVER_AFU_CONTEXT_RESET != p_ctx->return_flags ) #endif CHECK_RC(1, "ioctl_dk_capi_recover_ctx flag verification failed"); rc = ctx_reinit(p_ctx); CHECK_RC(rc, "ctx_reinit() failed"); #ifndef _AIX pthread_create(&thread2, NULL, ctx_rrq_rx, p_ctx); #endif rc = do_io(p_ctx, stride); if ( rc == 2) rc=0; else CHECK_RC(rc, "1st IO attempt didn't fail"); #ifdef _AIX last_lba = p_ctx->last_phys_lba; #else last_lba = p_ctx->last_lba; #endif #ifdef _AIX p_ctx->flags = DK_VF_HC_TUR; p_ctx->hint = DK_HINT_SENSE; #else p_ctx->hint = DK_CXLFLASH_VERIFY_HINT_SENSE; #endif rc = ioctl_dk_capi_verify(p_ctx); CHECK_RC(rc, "ioctl_dk_capi_verify failed\n"); #ifdef _AIX if ( 0 != p_ctx->return_flags ) CHECK_RC(1, "ioctl_dk_capi_verify flag verification failed"); #endif if ( p_ctx->verify_last_lba != last_lba ) CHECK_RC(1, "ioctl_dk_capi_verify last_lba verification failed"); // After adapter reset, // AFU interrupt monitoring thread need to be restarted. //rc = pthread_create(&threadId, NULL, ctx_rrq_rx, p_ctx); //CHECK_RC(rc, "pthread_create failed"); // Re-start the io using new context if (2 == cmd) { //its for long run #ifndef _AIX pthread_cancel(thread2); #endif rc = keep_doing_eeh_test(p_ctx); } else { //its for one attempt, sanity check of eeh debug("%d:Try once more IO & expecting to pass this time..\n",pid); rc = do_io(p_ctx, stride); CHECK_RC(rc, "do_io() failed"); } #ifndef _AIX pthread_cancel(thread2); #endif cleanup(p_ctx, threadId); return rc; }