]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
freetdm: improve IO stats (cherry picked from R2 branch)
authorMoises Silva <moy@sangoma.com>
Fri, 26 Nov 2010 20:49:18 +0000 (15:49 -0500)
committerMoises Silva <moy@sangoma.com>
Fri, 26 Nov 2010 20:49:18 +0000 (15:49 -0500)
libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c
libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
libs/freetdm/src/include/private/ftdm_core.h

index 1b906a2004ad522613f3c34f8e90ac4b502051a0..62d6d023b8499a138146619a2349fac4fb6d11a1 100644 (file)
@@ -655,32 +655,32 @@ void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len)
 
        memcpy(&l1_frame.data, data, len);
 
-       if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_CRC)) {
+       if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_CRC)) {
                l1_frame.flags |= SNG_L1FRAME_ERROR_CRC;
        }
 
-       if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_FRAME)) {
+       if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_FRAME)) {
                l1_frame.flags |= SNG_L1FRAME_ERROR_FRAME;
        }
        
-       if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_ABORT)) {
+       if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_ABORT)) {
                l1_frame.flags |= SNG_L1FRAME_ERROR_ABORT;
        }
 
-       if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_FIFO)) {
+       if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_FIFO)) {
                l1_frame.flags |= SNG_L1FRAME_ERROR_FIFO;
        }
 
-       if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_DMA)) {
+       if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_DMA)) {
                l1_frame.flags |= SNG_L1FRAME_ERROR_DMA;
        }
 
-       if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES)) {
+       if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES)) {
                /* Should we trigger congestion here? */                
                l1_frame.flags |= SNG_L1FRAME_QUEUE_THRES;
        }
 
-       if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL)) {
+       if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL)) {
                /* Should we trigger congestion here? */
                l1_frame.flags |= SNG_L1FRAME_QUEUE_FULL;
        }
index c13455dd211adf74fdedb568be8b2076c115c77c..c20ad82a3b632acdd325e0b2b4d5ea72e478c592 100644 (file)
@@ -513,7 +513,10 @@ static FIO_OPEN_FUNCTION(wanpipe_open)
        wanpipe_tdm_api_t tdm_api;
 
        memset(&tdm_api,0,sizeof(tdm_api));
+
        sangoma_tdm_flush_bufs(ftdmchan->sockfd, &tdm_api);
+       sangoma_flush_stats(ftdmchan->sockfd, &tdm_api);
+       memset(&ftdmchan->iostats, 0, sizeof(ftdmchan->iostats));
 
        if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921 || ftdmchan->type == FTDM_CHAN_TYPE_DQ931) {
                ftdmchan->native_codec = ftdmchan->effective_codec = FTDM_CODEC_NONE;
@@ -750,6 +753,7 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
        case FTDM_COMMAND_FLUSH_IOSTATS:
                {
                        err = sangoma_flush_stats(ftdmchan->sockfd, &tdm_api);
+                       memset(&ftdmchan->iostats, 0, sizeof(ftdmchan->iostats));
                }
                break;
        case FTDM_COMMAND_SET_RX_QUEUE_SIZE:
@@ -777,44 +781,110 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
        return FTDM_SUCCESS;
 }
 
-static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx_stats)
+static void wanpipe_write_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_tx_hdr_t *tx_stats)
 {
-       ftdmchan->iostats.stats.rx.flags = 0;
+       ftdmchan->iostats.tx.errors = tx_stats->wp_api_tx_hdr_errors;
+       ftdmchan->iostats.tx.queue_size = tx_stats->wp_api_tx_hdr_max_queue_length;
+       ftdmchan->iostats.tx.queue_len = tx_stats->wp_api_tx_hdr_number_of_frames_in_queue;
+       
+       if (ftdmchan->iostats.tx.queue_len >= (0.8 * ftdmchan->iostats.tx.queue_size)) {
+               ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Tx Queue length exceeded 80% threshold (%d/%d)\n",
+                                                       ftdmchan->iostats.tx.queue_len, ftdmchan->iostats.tx.queue_size);
+               ftdm_set_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
+       } else if (ftdm_test_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_THRES)){
+               ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Tx Queue length reduced 80% threshold (%d/%d)\n",
+                                                       ftdmchan->iostats.tx.queue_len, ftdmchan->iostats.tx.queue_size);
+               ftdm_clear_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
+       }
+       
+       if (ftdmchan->iostats.tx.queue_len >= ftdmchan->iostats.rx.queue_size) {
+               ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Tx Queue Full (%d/%d)\n",
+                                         ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
+               ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
+       } else if (ftdm_test_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL)){
+               ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Tx Queue no longer full (%d/%d)\n",
+                                         ftdmchan->iostats.tx.queue_len, ftdmchan->iostats.tx.queue_size);
+               ftdm_clear_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
+       }
+
+       if (ftdmchan->iostats.tx.idle_packets < tx_stats->wp_api_tx_hdr_number_of_frames_in_queue) {
+               ftdmchan->iostats.tx.idle_packets = tx_stats->wp_api_tx_hdr_tx_idle_packets;
+               ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Tx idle:  %d\n", ftdmchan->iostats.tx.idle_packets);
+       }
 
-       ftdmchan->iostats.stats.rx.errors = rx_stats->wp_api_rx_hdr_errors;
-       ftdmchan->iostats.stats.rx.rx_queue_size = rx_stats->wp_api_rx_hdr_max_queue_length;
-       ftdmchan->iostats.stats.rx.rx_queue_len = rx_stats->wp_api_rx_hdr_number_of_frames_in_queue;
+       if (!ftdmchan->iostats.tx.packets) {
+               ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "First packet write stats: Tx queue len: %d, Tx queue size: %d, Tx idle: %d\n", 
+                               ftdmchan->iostats.tx.queue_len, 
+                               ftdmchan->iostats.tx.queue_size,
+                               ftdmchan->iostats.tx.idle_packets);
+       }
+
+       ftdmchan->iostats.tx.packets++;
+}
+
+static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx_stats)
+{
+       ftdmchan->iostats.rx.errors = rx_stats->wp_api_rx_hdr_errors;
+       ftdmchan->iostats.rx.queue_size = rx_stats->wp_api_rx_hdr_max_queue_length;
+       ftdmchan->iostats.rx.queue_len = rx_stats->wp_api_rx_hdr_number_of_frames_in_queue;
        
-       if (rx_stats->wp_api_rx_hdr_error_map & (1<<WP_ABORT_ERROR_BIT)) {
-               ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_ABORT);
+       if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_ABORT_ERROR_BIT))) {
+               ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_ABORT);
+       } else {
+               ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_ABORT);
        }
-       if (rx_stats->wp_api_rx_hdr_error_map & (1<<WP_DMA_ERROR_BIT)) {
-               ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_DMA);
+
+       if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_DMA_ERROR_BIT))) {
+               ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_DMA);
+       } else {
+               ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_DMA);
        }
-       if (rx_stats->wp_api_rx_hdr_error_map & (1<<WP_FIFO_ERROR_BIT)) {
-               ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_FIFO);
+
+       if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_FIFO_ERROR_BIT))) {
+               ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FIFO);
+       } else {
+               ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FIFO);
        }
-       if (rx_stats->wp_api_rx_hdr_error_map & (1<<WP_CRC_ERROR_BIT)) {
-               ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_CRC);
+
+       if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_CRC_ERROR_BIT))) {
+               ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_CRC);
+       } else {
+               ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_CRC);
        }
-       if (rx_stats->wp_api_rx_hdr_error_map & (1<<WP_FRAME_ERROR_BIT)) {
-               ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_FRAME);
+
+       if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_FRAME_ERROR_BIT))) {
+               ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FRAME);
+       } else {
+               ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FRAME);
        }
 
-       if (ftdmchan->iostats.stats.rx.rx_queue_len >= (0.8*ftdmchan->iostats.stats.rx.rx_queue_size)) {
-               ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Rx Queue length exceeded threshold (%d/%d)\n",
-                                                                                                       ftdmchan->iostats.stats.rx.rx_queue_len, ftdmchan->iostats.stats.rx.rx_queue_size);
-               
-               ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
+       if (ftdmchan->iostats.rx.queue_len >= (0.8 * ftdmchan->iostats.rx.queue_size)) {
+               ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Rx Queue length exceeded 80% threshold (%d/%d)\n",
+                                                       ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
+               ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
+       } else if (ftdm_test_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES)){
+               /* any reason we have wanpipe_tdm_api_iface.h in ftmod_wanpipe/ dir? */
+               ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Rx Queue length reduced 80% threshold (%d/%d)\n",
+                                                       ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
+               ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
        }
        
-       if (ftdmchan->iostats.stats.rx.rx_queue_len >= ftdmchan->iostats.stats.rx.rx_queue_size) {
+       if (ftdmchan->iostats.rx.queue_len >= ftdmchan->iostats.rx.queue_size) {
                ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Rx Queue Full (%d/%d)\n",
-                                         ftdmchan->iostats.stats.rx.rx_queue_len, ftdmchan->iostats.stats.rx.rx_queue_size);
-               
-               ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
+                                         ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
+               ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
+       } else if (ftdm_test_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL)){
+               ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Rx Queue no longer full (%d/%d)\n",
+                                         ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
+               ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
        }
-       return;
+
+       if (!ftdmchan->iostats.rx.packets) {
+               ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "First packet read stats: Rx queue len: %d, Rx queue size: %d\n", 
+                               ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
+       }
+
+       ftdmchan->iostats.rx.packets++;
 }
 
 /**
@@ -875,6 +945,9 @@ static FIO_WRITE_FUNCTION(wanpipe_write)
        /* should we be checking if bsent == *datalen here? */
        if (bsent > 0) {
                *datalen = bsent;
+               if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS)) {
+                       wanpipe_write_stats(ftdmchan, &hdrframe);
+               }
                return FTDM_SUCCESS;
        }
 
index 06f899c8c93fddcfc3f171e3733f4ca68fe8a475..7683ec71453b42dfc9d06b06a114e2ad0cd0db2e 100644 (file)
@@ -368,30 +368,32 @@ typedef struct {
 } ftdm_channel_history_entry_t;
 
 typedef enum {
-       FTDM_IOSTATS_ERROR_CRC                  = (1<<0),
-       FTDM_IOSTATS_ERROR_FRAME                = (1<<1),
-       FTDM_IOSTATS_ERROR_ABORT                = (1<<2),
-       FTDM_IOSTATS_ERROR_FIFO                 = (1<<3),
-       FTDM_IOSTATS_ERROR_DMA                  = (1<<4),
-       FTDM_IOSTATS_ERROR_QUEUE_THRES  = (1<<5), /* Queue reached high threshold */
-       FTDM_IOSTATS_ERROR_QUEUE_FULL   = (1<<6), /* Queue is full */
+       FTDM_IOSTATS_ERROR_CRC          = (1 << 0),
+       FTDM_IOSTATS_ERROR_FRAME        = (1 << 1),
+       FTDM_IOSTATS_ERROR_ABORT        = (1 << 2),
+       FTDM_IOSTATS_ERROR_FIFO         = (1 << 3),
+       FTDM_IOSTATS_ERROR_DMA          = (1 << 4),
+       FTDM_IOSTATS_ERROR_QUEUE_THRES  = (1 << 5), /* Queue reached high threshold */
+       FTDM_IOSTATS_ERROR_QUEUE_FULL   = (1 << 6), /* Queue is full */
 } ftdm_iostats_error_type_t;
 
 typedef struct {
-       union {
-               struct {
-                       uint32_t        errors;
-                       uint16_t        flags;
-                       uint8_t         rx_queue_size;  /* max queue size configured */
-                       uint8_t         rx_queue_len;   /* Current number of elements in queue */
-               } rx;
-               struct {
-                       uint32_t        errors;
-                       uint16_t        flags;
-                       uint8_t         tx_queue_size;  /* max queue size configured */
-                       uint8_t         tx_queue_len;   /* Current number of elements in queue */
-               } tx;
-       } stats;
+       struct {
+               uint32_t errors;
+               uint16_t flags;
+               uint8_t  queue_size;    /* max queue size configured */
+               uint8_t  queue_len;     /* Current number of elements in queue */
+               uint64_t packets;
+       } rx;
+
+       struct {
+               uint32_t errors;
+               uint16_t flags;
+               uint8_t  idle_packets;
+               uint8_t  queue_size;    /* max queue size configured */
+               uint8_t  queue_len;     /* Current number of elements in queue */
+               uint64_t packets;
+       } tx;
 } ftdm_channel_iostats_t;
 
 /* 2^8 table size, one for each byte (sample) value */