All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wolfgang Grandegger <wg@domain.hid>
To: xenomai-core <xenomai@xenomai.org>
Subject: [Xenomai-core] BUG: sleeping function called from invalid context at kernel/xenomai/skins/posix/syscall.c:272
Date: Wed, 18 Oct 2006 19:23:32 +0200	[thread overview]
Message-ID: <45366314.5000904@domain.hid> (raw)

[-- Attachment #1: Type: text/plain, Size: 203 bytes --]

Hello,

when I start the RT-Socket-CAN program rtcan_rtt.c, I get the attached 
error message. Any idea where the problem could be? It was working with 
Xenomai under Linux 2.4.25.

Thanks.

Wolfgang.



[-- Attachment #2: BUG.log --]
[-- Type: text/x-log, Size: 910 bytes --]

bash-3.00# rtcan_rtt rtcan0 rtcan1
BUG: sleeping function called from invalid context at kernel/xenomai/skins/posix/syscall.c:272
in_atomic():0, irqs_disabled():1
Call Trace:
[C30C9E00] [C000D7E8] show_stack+0x48/0x190 (unreliable)
[C30C9E30] [C0013D08] __might_sleep+0xc4/0xf0
[C30C9E50] [C0066514] __pthread_setschedparam+0xe0/0x2c0
[C30C9EB0] [C00492AC] losyscall_event+0xc8/0x1e0
[C30C9EE0] [C003A330] __ipipe_dispatch_event+0x94/0x19c
[C30C9F30] [C0009290] __ipipe_syscall_root+0x44/0xfc
[C30C9F40] [C00041C0] DoSyscall+0x24/0x60
1 3
TX txsock=897, ifr_name=rtcan0
RX rxsock=898, ifr_name=rtcan1
Round-Trip-Time test rtcan0 -> rtcan1 with CAN ID 0x1
Cycle time: 10000 us
All RTT timing figures are in us.
Messages RTTlast RTT_avg RTT_min RTT_max Overruns
     100    1022     997     992    1026        0
     200     998    1006     990    1034        0
     300     998    1005     990    1034        0

[-- Attachment #3: rtcan_rtt.c --]
[-- Type: text/x-csrc, Size: 9695 bytes --]

/*
 * Round-Trip-Time Test - sends and receives messages and measures the
 *                        time in between.
 *
 * Copyright (C) 2006 Wolfgang Grandegger <wg@domain.hid>
 *
 * Based on RTnet's examples/xenomai/posix/rtt-sender.c.
 *
 * Copyright (C) 2002 Ulrich Marx <marx@domain.hid>
 *               2002 Marc Kleine-Budde <kleine-budde@domain.hid>
 *               2006 Jan Kiszka <jan.kiszka@domain.hid>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <errno.h>
#include <mqueue.h>
#include <signal.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <getopt.h>
#include <netinet/in.h>
#include <sys/mman.h>

#include "rtdm/rtcan.h"

static unsigned int cycle = 10000; /* 10 ms */
static can_id_t can_id = 0x1;

static pthread_t txthread, rxthread;
static int txsock, rxsock;
static mqd_t mq;
static int txcount, rxcount;
static int overruns;

struct rtt_stat {    
    long long rtt;
    long long rtt_min;
    long long rtt_max;
    long long rtt_sum;
    long long rtt_sum_last;
    int counts_per_sec;
};

static void print_usage(char *prg)
{
    fprintf(stderr, 
	    "Usage: %s  [Options] <tx-can-interface> <rx-can-interface>\n"
	    "Options:\n"
	    " -i, --id=ID   CAN Identifier (default = 0x1)\n"
	    " -c, --cycle   Cycle time in us (default = 10000us)\n",
	    prg);
}

void *transmitter(void *arg)
{
    struct sched_param  param = { .sched_priority = 80 };
    struct timespec next_period;
    struct timespec time;
    struct can_frame frame;
    long long *rtt_time = (long long *)&frame.data;

    /* Pre-fill CAN frame */
    frame.can_id = can_id;
    frame.can_dlc = sizeof(*rtt_time);

    pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);

    clock_gettime(CLOCK_MONOTONIC, &next_period);

    while(1) {
        next_period.tv_nsec += cycle * 1000;
        if (next_period.tv_nsec >= 1000000000) {
            next_period.tv_nsec = 0;
            next_period.tv_sec++;
        }

        clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_period, NULL);

	if (rxcount != txcount) {
	    overruns++;
	    continue;
	}

        clock_gettime(CLOCK_MONOTONIC, &time);
	*rtt_time = time.tv_sec * 1000000000LL + time.tv_nsec;

        /* Transmit the message containing the local time */
	if (send(txsock, (void *)&frame, sizeof(can_frame_t), 0) < 0) {	    
            if (errno == EBADF)
                printf("terminating transmitter thread\n");
            else
                perror("send failed");
            return NULL;
        }
	txcount++;
    }
}


void *receiver(void *arg)
{
    struct sched_param param = { .sched_priority = 82 };
    struct timespec time;
    struct can_frame frame;
    long long *rtt_time = (long long *)frame.data;
    struct rtt_stat rtt_stat = {0, LONG_LONG_MAX, LONG_LONG_MIN, 0, 0, 0};

    pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);

    rtt_stat.counts_per_sec = 1000000 / cycle;

    while (1) {
	if (recv(rxsock, (void *)&frame, sizeof(can_frame_t), 0) < 0) {
	    if (errno == EBADF)
                printf("terminating receiver thread\n");
            else
                perror("recv failed");
            return NULL;
        }

	clock_gettime(CLOCK_MONOTONIC, &time);
	if (rxcount++ > 0) {
	    rtt_stat.rtt = (time.tv_sec * 1000000000LL + 
			    time.tv_nsec - *rtt_time);
	    rtt_stat.rtt_sum += rtt_stat.rtt;
	    if (rtt_stat.rtt <  rtt_stat.rtt_min)
		rtt_stat.rtt_min = rtt_stat.rtt;
	    if (rtt_stat.rtt > rtt_stat.rtt_max)
		rtt_stat.rtt_max = rtt_stat.rtt;
	}
	if ((rxcount % rtt_stat.counts_per_sec) == 0) {
	    mq_send(mq, (char *)&rtt_stat, sizeof(rtt_stat), 0);
	    rtt_stat.rtt_sum_last = rtt_stat.rtt_sum;
	}
    }
}

void catch_signal(int sig)
{
    mq_close(mq);
}


int main(int argc, char *argv[])
{
    struct sched_param param = { .sched_priority = 1 };
    struct sockaddr_can addr;
    pthread_attr_t thattr;
    struct mq_attr mqattr;
    struct can_filter rxfilter[1];
    struct rtt_stat rtt_stat;
    char mqname[32];
    struct ifreq ifr;
    int ret, opt;

    struct option long_options[] = {
	{ "id", required_argument, 0, 'i'},
	{ "cycle", required_argument, 0, 'c'},
	{ 0, 0, 0, 0},
    };

    while ((opt = getopt_long(argc, argv, "i:c:", 
			      long_options, NULL)) != -1) {
	switch (opt) {
	case 'c':
	    cycle = atoi(optarg);
	    break;

	case 'i':
	    can_id = strtoul(optarg, NULL, 0);
	    break;

	default:
	    fprintf(stderr, "Unknown option %c\n", opt);
	    print_usage(argv[0]);
	    break;
	}
    }

    printf("%d %d\n", optind, argc);
    if (optind + 2 != argc) {
	print_usage(argv[0]);
	exit(0);
    }

    /* Create and configure TX socket */
    if ((txsock = socket(PF_CAN, SOCK_RAW, 0)) < 0) {
	perror("TX socket failed");
	return -1;
    }

    strncpy(ifr.ifr_name, argv[optind], IFNAMSIZ);
    printf("TX txsock=%d, ifr_name=%s\n", txsock, ifr.ifr_name);

    if (ioctl(txsock, SIOCGIFINDEX, &ifr) < 0) {
	perror("TX ioctl SIOCGIFINDEX failed");
	goto failure1;
    }

    memset(&addr, 0, sizeof(addr));
    addr.can_ifindex = ifr.ifr_ifindex;
    addr.can_family = AF_CAN;
    if (bind(txsock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
	perror("TX bind failed\n");
	goto failure1;
    }

    /* Create and configure RX socket */
    if ((rxsock = socket(PF_CAN, SOCK_RAW, 0)) < 0) {
	perror("RX socket failed");
	goto failure1;
    }

    strncpy(ifr.ifr_name, argv[optind + 1], IFNAMSIZ);
    printf("RX rxsock=%d, ifr_name=%s\n", rxsock, ifr.ifr_name);

    if (ioctl(rxsock, SIOCGIFINDEX, &ifr) < 0) {
	perror("RX ioctl SIOCGIFINDEX failed");
	goto failure2;
    }

    /* We only want to receive our own messages */
    rxfilter[0].can_id = can_id;
    rxfilter[0].can_mask = 0x3ff;
    if (setsockopt(rxsock, SOL_CAN_RAW, CAN_RAW_FILTER, 
		   &rxfilter, sizeof(struct can_filter)) < 0) {
	perror("RX setsockopt CAN_RAW_FILTER failed");
	goto failure2;
    }
    memset(&addr, 0, sizeof(addr));
    addr.can_ifindex = ifr.ifr_ifindex;
    addr.can_family = AF_CAN;
    if (bind(rxsock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
	perror("RX bind failed\n");
	goto failure2;
    }

    signal(SIGTERM, catch_signal);
    signal(SIGINT, catch_signal);
    signal(SIGHUP, catch_signal);
    mlockall(MCL_CURRENT|MCL_FUTURE);

    printf("Round-Trip-Time test %s -> %s with CAN ID 0x%x\n", 
	   argv[optind], argv[optind + 1], can_id);
    printf("Cycle time: %d us\n", cycle);
    printf("All RTT timing figures are in us.\n");

    /* Create statistics message queue */
    snprintf(mqname, sizeof(mqname), "/rtcan_rtt-%d", getpid());
    mqattr.mq_flags   = 0;
    mqattr.mq_maxmsg  = 100;
    mqattr.mq_msgsize = sizeof(struct rtt_stat);
    mq = mq_open(mqname, O_RDWR | O_CREAT | O_EXCL, 0600, &mqattr);
    if (mq == (mqd_t)-1) {
        perror("opening mqueue failed");
        goto failure2;
    }

    /* Create receiver RT-thread */
    pthread_attr_init(&thattr);
    pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
    pthread_attr_setstacksize(&thattr, PTHREAD_STACK_MIN);
    ret = pthread_create(&rxthread, &thattr, &receiver, NULL);
    if (ret) {
	fprintf(stderr, "%s: pthread_create(receiver) failed\n", 
		strerror(-ret));
        goto failure3;
    }

    /* Create transitter RT-thread */
    ret = pthread_create(&txthread, &thattr, &transmitter, NULL);
    if (ret) {
	fprintf(stderr, "%s: pthread_create(transmitter) failed\n", 
		strerror(-ret));
	goto failure4;
    }

    pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);

    printf("Messages RTTlast RTT_avg RTT_min RTT_max Overruns\n");

    while (1) {
	long long rtt_avg;

        ret = mq_receive(mq, (char *)&rtt_stat, sizeof(rtt_stat), NULL);
        if (ret != sizeof(rtt_stat)) {
	    if (ret < 0) {
		if (errno == EBADF)
		    printf("terminating mq_receive\n");
		else
		    perror("mq_receive failed");
	    } else
		fprintf(stderr, 
			"mq_receive returned invalid length %d\n", ret);
            break;
	}

	rtt_avg = ((rtt_stat.rtt_sum - rtt_stat.rtt_sum_last) /
		   rtt_stat.counts_per_sec);
	printf("%8d %7ld %7ld %7ld %7ld %8d\n", rxcount, 
	       (long)(rtt_stat.rtt / 1000), (long)(rtt_avg / 1000),
	       (long)(rtt_stat.rtt_min / 1000),
	       (long)(rtt_stat.rtt_max / 1000),
	       overruns);
    }

    /* This call also leaves primary mode, required for socket cleanup. */
    printf("shutting down\n");

    /* Important: First close the sockets! */
    while ((close(rxsock) < 0) && (errno == EAGAIN)) {
        printf("RX socket busy - waiting...\n");
        sleep(1);
    }
    while ((close(txsock) < 0) && (errno == EAGAIN)) {
        printf("TX socket busy - waiting...\n");
        sleep(1);
    }
    
    pthread_join(txthread, NULL);
    pthread_kill(rxthread, SIGHUP);
    pthread_join(rxthread, NULL);

    return 0;

 failure4:
    pthread_kill(rxthread, SIGHUP);
    pthread_join(rxthread, NULL);
 failure3:
    mq_close(mq);
 failure2:
    close(rxsock);
 failure1:
    close(txsock);

    return 1;
}

             reply	other threads:[~2006-10-18 17:23 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-10-18 17:23 Wolfgang Grandegger [this message]
2006-10-18 19:19 ` [Xenomai-core] BUG: sleeping function called from invalid context at kernel/xenomai/skins/posix/syscall.c:272 Jan Kiszka
2006-10-19  7:23   ` Wolfgang Grandegger
2006-10-19 14:43   ` Wolfgang Grandegger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=45366314.5000904@domain.hid \
    --to=wg@domain.hid \
    --cc=xenomai@xenomai.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.