Date: Mon, 24 Apr 2006 00:14:53 -0700 (PDT) From: "R. B. Riddick" <arne_woerner@yahoo.com> To: Erin E Conn <econn@nc.rr.com> Cc: freebsd-multimedia@freebsd.org Subject: Re: Rebooting problems with /dev/cxm0 Message-ID: <20060424071453.4677.qmail@web30314.mail.mud.yahoo.com> In-Reply-To: <444C25D7.9050600@nc.rr.com>
index | next in thread | previous in thread | raw e-mail
[-- Attachment #1 --] --- Erin E Conn <econn@nc.rr.com> wrote: > After some rebuilding and reinstalling of ports, I was able to cat > /dev/cxm0 to a file in my home directory for about half an hour with no > dma errors or lockups. I then stopped the cat and tried 'mplayer -cache > 4096 /dev/cxm0', and my machine locked up after about 2 minutes. The > display continues to update; my dockapps in fluxbox are still > functioning and updating, but the machine does not respond to any > network traffic or input devices and the video and audio from /dev/cxm0 > have halted. Nothing is being logged to /var/log/messages at the time. I > tried it again while keeping an eye on the console in case there are dma > problems preventing anything being written to the log: > > cxm0:encoder dma status 0xb > # MACHINE STOPPED RESPONDING HERE > cmx0:encoder dma status 0xb > ad0: TIMEOUT - WRITE_DMA retrying (1 retry left) LBA=22069947 > ad0: TIMEOUT - WRITE_DMA retrying (0 retries left) LBA=22069947 > dc0: watchdog timeout > dc0: failed to force tx and rx to idle state > ad0: FAILURE - WRITE_DMA timed out LBA=22069947 > ad0: FAILURE - READ_DMA timed out LBA=20487259 > > The above messages continue to be output to the console and I have to > manually restart the computer. > That sounds familiar... :-) I attached a variation of my very special cxm-data-transfer-program, that just copies the data to your disc (hopefully in the right order... :-)). After examining some areas of the code (just in case I am evil), it can be compiled with c++ -o dd3 dd3.c -O3 and it can be tested with ./dd3 /dev/cxm0 <outputfile> <time of day in sec since 1970 when to stop> E.g.: ./dd3 /dev/cxm0 /tmp/blubberblah.mpg 1146862400 where the seconds since 1970 can be found via date +%s which gives the current time in seconds since 1970 or via date -j +%s 2000 which gives the seconds since 1970 when it is 8 p.m. today. I hope, I got the license right... It should be a BSD license or so... In my opinion this dd3.c tool should result in more stability (currently more then 66 days uptime...)... -Arne __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com [-- Attachment #2 --] // $Id: dd2.c,v 1.3 2005/12/08 01:17:49 aw Exp aw $ #include <errno.h> #include <fcntl.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/uio.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <signal.h> #include <time.h> #include <sys/socket.h> #include <sys/wait.h> #include <fcntl.h> #include <netinet/in.h> #include <arpa/inet.h> #include <syslog.h> #include <stdarg.h> #define check(e) if (!(e)) _check(__func__,__FILE__,__LINE__,#e) void _check(const char * const fu, const char * const fi, const int li, const char * const wh) { printf("ERR in %s, %s, %d, reason %s\n",fu,fi,li,wh); syslog(LOG_DEBUG,"ERR in %s, %s, %d, reason %s\n",fu,fi,li,wh); killpg(0,SIGKILL); } bool in = false; bool to = false; bool te = false; void timeout(const int sno) { to = true; if (sno == SIGTERM) te = true; } void requestInfo(const int sno) { in = true; } void stats(const uint64_t bc, const time_t dt) { fprintf(stderr, "%lldbytes read in %dsecs: %.3fMbytes/sec\n", bc,dt,bc*(1./(1024.*1024.))/dt); } void setOff(char * bu, const uint64_t bc) { (*(uint64_t*)(bu-4-8)) = bc; } uint64_t getOff(char * bu) { return *(uint64_t*)(bu-4-8); } void setSz(char * const bu, const int cc) { (*(int*)(bu-4)) = cc; } int getSz(char * bu) { return *(int*)(bu-4); } void mark(char * bu, const bool s) { (*(bool*)(bu-(4+8+4))) = s; } void markFull(char * bu) { mark(bu,true); } void markEmpty(char * bu) { mark(bu,false); } bool isFull(char * bu) { return bu[-(4+8+4)]!=0; } char * get(char * const buf, const int bno, const int bsz) { return buf+bno*bsz+4+8+4; } void disc(int& ouf, char * const bu) { const int sz = getSz(bu); lseek(ouf,getOff(bu),SEEK_SET); ualarm(900*1000,0); const int r = write(ouf,bu,sz); ualarm(0,0); if (r == sz) markEmpty(bu); else if (r < 0) { printf("write error r%d errno%d\n",r,errno); exit(1); } else { printf("incomplete write r%d\n",r); exit(3); } } void markBlock(const int d, const bool blck) { int flags = fcntl(d,F_GETFL); check(flags != -1); if (blck) flags &= ~O_NONBLOCK; else flags |= O_NONBLOCK; check(fcntl(d,F_SETFL,&flags) != -1); } void flusher(const bool fff, const char * const fn, char * const buf, const int buc, const int bsz) { int maxSZ = 0; int maxBN = -1; int svf = socket(AF_INET, SOCK_STREAM, 0); if (svf >= 0) { markBlock(svf,false); struct sockaddr_in a; bzero(&a,sizeof(a)); a.sin_family = AF_INET; a.sin_addr.s_addr = 0; const int mp = 1000; const int pb = 20000 + (fff?mp:0); int p; for (p=0; p<1000; p++) { a.sin_port = htons(pb+p); if (!bind(svf,(struct sockaddr*)&a,sizeof(a))) { if (listen(svf,1)) p = mp; break; } } if (p == mp) { close(svf); svf = -1; printf("no network service possible\n"); } else printf("network service at port %d\n",pb+p); } int ouf = -1; int fno = 0; for (bool allEmpty=false; !te || !allEmpty;) { allEmpty = true; for (int i=0; i<buc; i++) { char * bu = get(buf,i,bsz); if (!isFull(bu)) continue; if (getSz(bu) > maxSZ) maxSZ = getSz(bu); if (i > maxBN) maxBN = i; if (!fff && ouf < 0) { char FN[strlen(fn)+20+1]; check(snprintf(FN,sizeof(FN)-5,"%s.%d",fn,fno)<sizeof(FN)-2); fno++; ouf = open(FN,O_WRONLY|O_CREAT|O_EXCL,0666); check(ouf >= 0); const bool ready = false; ualarm(500*1000,0); check(write(ouf,&ready,sizeof(ready))==sizeof(ready)); ualarm(0,0); } allEmpty = false; if (!false) { if (!fff) disc(ouf,bu); else usleep(50*1000); } } if (allEmpty) usleep(50*1000); } if (ouf >= 0) { check(lseek(ouf,0,SEEK_SET)==0); const bool ready = true; check(write(ouf,&ready,sizeof(ready))==sizeof(ready)); check(close(ouf) != -1); printf("marked ouf ready %d\n",ready); } printf("flusher terminates ... now! [maxSZ%d maxBN%d]\n",maxSZ,maxBN); exit(0); } void next(char * const buf, char *& bu, const int bsz, int& cc, const uint64_t bc, int& bno, const int buc) { if (bu != 0) { setSz(bu,cc); check(getOff(bu)+cc == bc); markFull(bu); } for (bno=0; bno<buc; bno++) { bu = get(buf,bno,bsz); if (!isFull(bu)) { cc = 0; setOff(bu,bc); return; } } bu = 0; } void feedFromDevice(bool& to, int& r, const char * const devNam, time_t& now, const time_t ets, const time_t sts, uint64_t& bc, const int re, const int bs, int& cc, char * const buf, char *& bu, const int buc, const int bsz, int& bno) { const int inf = open(devNam,O_RDONLY); for (int i=0; !to && now<ets; i++) { const int mi = 100; if (i > mi) { now = time(0); if (in) { in = false; stats(bc,now-sts); } i = 0; } check(re <= bs+re-cc); ualarm(2*1000*1000,0); r = read(inf,bu+cc,re); ualarm(0,0); if (r < 0) break; if (r == 0) continue; cc += r; bc += r; if (cc >= bs) { next(buf,bu,bsz,cc,bc,bno,buc); if (bu == 0) { printf("no free buffer\n"); break; } i = mi; } } close(inf); } int main(const int argc, const char * const * const argv) { if (argc != 1+3) return 1; openlog("pvr-dd2",LOG_PID,LOG_USER); signal(SIGPIPE,SIG_IGN); siginterrupt(SIGPIPE,true); signal(SIGINFO,requestInfo); siginterrupt(SIGINFO,false); signal(SIGTERM,timeout); siginterrupt(SIGTERM,true); signal(SIGALRM,timeout); siginterrupt(SIGALRM,true); time_t now = time(0); const time_t sts = now; const bool fff = argv[1][0]==0; const time_t ets = fff?-1:atoi(argv[3]); const int bs = 1<<20; const int re = bs/4; const int bsz = bs+re+4+8+4; const int buc = 8; char * buf = (char*) mmap(0,buc*bsz,PROT_READ|PROT_WRITE, MAP_ANON|MAP_NOCORE|MAP_NOSYNC|MAP_SHARED,-1,0); for (int i=0; i<buc; i++) markEmpty(get(buf,i,bsz)); const int fpid = fork(); if (fpid == 0) { flusher(fff,argv[2],buf,buc,bsz); exit(0); } if (fpid < 0) { printf("fork failed\n"); exit(1); } syslog(LOG_DEBUG,"me%d son%d\n",getpid(),fpid); uint64_t bc = 0; int bno = 0; int cc = 0; char * bu = get(buf,bno,bsz); setOff(bu,bc); while (!te && (ets==-1 || now<ets)) { to = false; int r; if (fff) ; else feedFromDevice(to,r,argv[1],now,ets,sts,bc,re,bs,cc, buf,bu,buc,bsz,bno); usleep(500*1000); next(buf,bu,bsz,cc,bc,bno,buc); if (bu == 0) { printf("no free buffer\n"); break; } int i=0; const int mi = 10*10; for (bool allEmpty=false; !allEmpty && i<mi; i++) { usleep(100*1000); allEmpty = true; for (int i=buc-1; i>=0; i--) if (isFull(get(buf,i,bsz))) { allEmpty = false; break; } } check(i < mi); now = time(0); fprintf(stderr, "bailed out (to%d te%d cc%d r%d errno%d): ", to,te,cc,r,errno); stats(bc,now-sts); usleep(500*1000); } { const int kr = kill(fpid,SIGTERM); printf("kill flusher process result: r%d errno%d\n",kr,errno); int status; wait(&status); } closelog(); return 0; }help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060424071453.4677.qmail>
