Juan, Found the problem. It is in the example. The reason you ceased to get notification is because the notification queue is full. For each notification a message is enqueued. When you get the notification, you need to extract that message via a read(). So I think all that is missing in your program is.
pfarg_msg_t msg; read(fd, &msg, sizeof(msg)); in the signal handler before pfm_restart(); In the case of trivial sampling, it is possible to request no notification messages be sent by setting a context flag. ctx.ctx_flags = PFM_FL_OVFL_NO_MSG pfm_create_context(&ctx, "default", .....) In either case, you will getting infinite number of notifications. On Thu, May 14, 2009 at 2:18 PM, stephane eranian <eran...@googlemail.com> wrote: > Juan, > > I am able to reproduce the problem with a modified mont_dear.c. There > it stops after the > 8th notification. This is quite strange given this is all self > monitoring. Let me investigate. > I also want to verify if this is IA-64 specific or not. > > > On Thu, May 14, 2009 at 11:49 AM, Juan Angel Lorenzo > <jalmailingli...@gmail.com> wrote: >> Hi, >> >> El mié, 13-05-2009 a las 14:11 +0200, stephane eranian escribió: >> >>> >>> > The number of notifications is the number of times the sampling buffer >>> > overflowed, isn't it? So why does it look limited to 31? I mean, even if >>> >>> Yes, assuming your resume monitoring() via pfm_restart() at the end of >>> each notification. >> >> Yes, as far as I saw, this is what the "mont_dear.c" code does. It >> resumes monitoring every time a notification is handled. But it looks >> there is a limit of 31 times the monitoring can be resumed. And then it >> stops. I don't understand why. I thought this process could be done >> infinite times. Could it be perhaps because of any limit in the >> operating system settings? >> >> >>> Did you read the pmds in the handler via pfm_read_pmds()? >>> >> Yes. Briefly, this is what I did (mixing code from mont_dear.c, >> mont_rr.c and notify_self.c): >> >> #include <perfmon/perfmon.h> >> #include <perfmon/perfmon_default_smpl.h> >> #include <perfmon/pfmlib_montecito.h> >> >> #define SMPL_PERIOD (40) >> #define M_PMD(x) (1UL<<(x)) >> #define DEAR_REGS_MASK (M_PMD(32)|M_PMD(33)|M_PMD(36)) >> >> typedef pfm_default_smpl_hdr_t dear_hdr_t; >> typedef pfm_default_smpl_entry_t dear_entry_t; >> typedef pfm_default_smpl_ctx_arg_t dear_ctx_t; >> >> static int ctx_fd; >> static char *event1_name = "data_ear_cache_lat4"; >> static pfarg_reg_t pd[NUM_PMDS]; >> >> >> static void >> sigio_handler(int n, struct siginfo *info, struct sigcontext *sc) >> { >> pfm_msg_t msg; >> pfm_mont_pmd_reg_t reg; >> int fd = ctx_fd; >> int r; >> >> if (fd != ctx_fd) { >> fatal_error("handler does not get valid file descriptor\n"); >> } >> >> if (event1_name && perfmonctl(fd, PFM_READ_PMDS, pd+1, 1) == -1) { >> fatal_error("PFM_READ_PMDS: %s", strerror(errno)); >> } >> >> r = read(fd, &msg, sizeof(msg)); >> if (r != sizeof(msg)) { >> fatal_error("cannot read overflow message: %s\n", strerror(errno)); >> } >> >> printf("PMD pfarg_reg_t.reg_num: %u\n",pd[1].reg_num); >> printf("PMD pfarg_reg_t.reg_value: %lu\n",pd[1].reg_value); >> reg = (pfm_mont_pmd_reg_t)pd[1].reg_value; >> printf("PMD32: 0x%016lx\n", reg.pmd32_mont_reg.dear_daddr); >> >> ........ >> >> /* >> * And resume monitoring >> */ >> if (perfmonctl(fd, PFM_RESTART,NULL, 0) == -1) { >> fatal_error("PFM_RESTART: %s", strerror(errno)); >> } >> } >> >> >> >> int >> main(int argc, char **argv) >> { >> >> pfarg_reg_t pc[NUM_PMCS]; >> pfmlib_input_param_t inp; >> pfmlib_output_param_t outp; >> pfmlib_event_t ev; >> dear_ctx_t ctx; >> pfarg_load_t load_args; >> pfmlib_options_t pfmlib_options; >> struct sigaction act; >> >> ...... >> unsigned long range_start, range_end; >> pfmlib_mont_input_param_t mont_inp; >> pfmlib_mont_output_param_t mont_outp; >> pfarg_dbreg_t dbrs[8]; >> >> ...... >> >> if (pfm_find_full_event(event1_name, &ev) != PFMLIB_SUCCESS) >> fatal_error("cannot find event %s\n", event1_name); >> >> inp.pfp_dfl_plm = PFM_PLM3|PFM_PLM0; >> >> /* >> * how many counters we use >> */ >> inp.pfp_event_count = 1; >> >> /* >> * propagate the event descriptor >> */ >> inp.pfp_events[0] = ev; >> >> >> mont_inp.pfp_mont_drange.rr_used = 1; >> mont_inp.pfp_mont_drange.rr_limits[0].rr_start = range_start; >> mont_inp.pfp_mont_drange.rr_limits[0].rr_end = range_end; >> >> if ((ret=pfm_dispatch_events(&inp, &mont_inp, >> &outp,&mont_outp)) != PFMLIB_SUCCESS) >> fatal_error("cannot configure events: %s\n", >> pfm_strerror(ret)); >> >> /* >> * now create the context for self monitoring/per-task >> */ >> if (perfmonctl(0, PFM_CREATE_CONTEXT, &ctx, 1) == -1 ) { >> if (errno == ENOSYS) { >> fatal_error("Your kernel does not have >> performance monitoring support!\n"); >> } >> fatal_error("Can't create PFM context %s\n", >> strerror(errno)); >> } >> >> ctx_fd = ctx.ctx_arg.ctx_fd; >> >> >> for (i=0; i < outp.pfp_pmc_count; i++) { >> pc[i].reg_num = outp.pfp_pmcs[i].reg_num; >> pc[i].reg_value = outp.pfp_pmcs[i].reg_value; >> } >> >> >> /* >> * figure out pmd mapping from output pmc >> */ >> for (i=0; i < outp.pfp_pmd_count; i++) >> pd[i].reg_num = outp.pfp_pmds[i].reg_num; >> >> /* >> * We want to get notified when the counter used for our first >> * event overflows >> */ >> pc[0].reg_flags |= PFM_REGFL_OVFL_NOTIFY; >> pc[0].reg_reset_pmds[0] |= 1UL << outp.pfp_pmds[1].reg_num; >> >> >> /* >> * initialize the PMD and the sampling period >> */ >> pd[0].reg_value = - SMPL_PERIOD; >> pd[0].reg_long_reset = - SMPL_PERIOD; >> pd[0].reg_short_reset = - SMPL_PERIOD; >> >> >> if (perfmonctl(ctx_fd, PFM_WRITE_DBRS, dbrs, >> mont_outp.pfp_mont_drange.rr_nbr_used) == -1) { >> fatal_error( "child: perfmonctl error PFM_WRITE_DBRS >> errno %d\n",errno); >> } >> >> >> if (perfmonctl(ctx_fd, PFM_WRITE_PMCS, pc, outp.pfp_pmc_count)) >> fatal_error("pfm_write_pmcs error errno %d\n",errno); >> >> if (perfmonctl(ctx_fd, PFM_WRITE_PMDS, pd, outp.pfp_pmd_count)) >> fatal_error("pfm_write_pmds error errno %d\n",errno); >> >> /* >> * attach context to stopped task >> */ >> load_args.load_pid = getpid(); >> if (perfmonctl(ctx_fd, PFM_LOAD_CONTEXT, &load_args, 1)) >> fatal_error("pfm_load_context error errno %d\n",errno); >> >> >> /* >> * setup asynchronous notification on the file descriptor >> */ >> ret = fcntl(ctx_fd, F_SETFL, fcntl(ctx_fd, F_GETFL, 0) | >> O_ASYNC); >> >> /* >> * get ownership of the descriptor >> */ >> ret = fcntl(ctx_fd, F_SETOWN, getpid()); >> >> /* >> * Let's roll now. >> */ >> pfm_self_start(ctx_fd); >> >> ....... >> >> pfm_self_stop(ctx_fd); >> >> close(ctx_fd); >> return 0; >> } >> >> >> There's one thing I'm not sure is right. There was a line in >> notify_self.c: >> >> pc[0].reg_reset_pmds[0] |= 1UL << outp.pfp_pmcs[1].reg_num; >> >> which gives me a "pfm_write_pmcs error errno 22" error in this code. I >> think it intends to set the byte 32th in the reg_reset_pmds[0] field, so >> I changed it to: >> >> pc[0].reg_reset_pmds[0] |= 1UL << outp.pfp_pmds[1].reg_num; >> >> So the code runs, but when I get a notification, the value of >> pd[1].reg_value, in the sigio_handler, is always 0. >> >> Again, thanks for the help and apologies for the long email. If this >> code is not clear enough, I can attach the whole file. >> >> Juan >> >> > ------------------------------------------------------------------------------ The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your production scanning environment may not be a perfect world - but thanks to Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700 Series Scanner you'll get full speed at 300 dpi even with all image processing features enabled. http://p.sf.net/sfu/kodak-com _______________________________________________ perfmon2-devel mailing list perfmon2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/perfmon2-devel