Re: Problem developing Linux kernel module

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Michael, hello!

Michael Blizek wrote:
Problem happens at c026023c line:
        if (unlikely(buf->offset + length > chan->subbuf_size))
c026023c:       8b 55 08                mov    0x8(%ebp),%edx
c026023f:       01 da                   add    %ebx,%edx
c0260241:       3b 50 04                cmp    0x4(%eax),%edx
c0260244:       76 0b                   jbe    c0260251 <_ipfix_send_msg+0x62>

Can anyone tell me what is problem here? 'length' is broken or could it
be that this is Relay bug?

Can you show me the C cade of these functions, especially _ipfix_send_msg,
struct ipfix_iobuf and how you fill this struct? A search for ipfix in the
kernel returns no results for me.

I'm working on kernel-mode IPFIX probe so this is something very new :)

int _ipfix_send_msg (struct ipfix_t *ifh, struct ipfix_iobuf *buf)
{
      if (if_msg.offset) {
              if (_ipfix_send_message(ifh, 0, &if_msg) > 0) {
printk("_ipfix_send_msg: _ipfix_send_message() (sending templates failed)\n");
                      return 1;
              }
      }

      relay_write(nf_pool.rchan, buf->buf, buf->buflen);
      if_lastaccess = jiffies_to_msecs(jiffies);
      return 0;
}

relay_write() is inline (kern/relay.c):

static inline void relay_write(struct rchan *chan,
                             const void *data,
                             size_t length)
{
      unsigned long flags;
      struct rchan_buf *buf;

      local_irq_save(flags);
      buf = chan->buf[smp_processor_id()];
      if (unlikely(buf->offset + length > chan->subbuf_size))
              length = relay_switch_subbuf(buf, length);
      memcpy(buf->data + buf->offset, data, length);
      buf->offset += length;
      local_irq_restore(flags);
}

if_iobuf got defined like this:

struct ipfix_iobuf
{
       size_t buflen;
       char buf[IPFIX_DEFAULT_BUFLEN+IPFIX_HDR_BYTES];
};

It's filled in ipfix_export_flush():

int ipfix_export_flush (void)
{
       struct ipfix_iobuf *buf;
       int ret = 0;

       spin_lock_bh(&nf_ipfix_lock);

       buf = &if_iobuf;

       if ((if_h == NULL) || (if_h -> offset == 0))
               return 0;

       _ipfix_write_hdr(buf);
       memcpy(buf->buf+buf->buflen, if_h->buf, if_h->offset);
       buf->buflen += if_h -> offset;

       ret = 0;

       if (_ipfix_send_msg(buf) > 0) {
               ret = 1;
       }
       else
       {
               if_h -> offset = 0;
               if_h -> nrec = 0;
       }

       spin_unlock_bh(&nf_ipfix_lock);

       return ret;
}

int _ipfix_write_hdr (struct ipfix_iobuf *buf)
{
       struct timespec ts;

       getnstimeofday(&ts);

       buf->buflen = 0;

       INSERTU16( buf->buf+buf->buflen, buf->buflen, IPFIX_VERSION );
       INSERTU16( buf->buf+buf->buflen, buf->buflen,
                  if_h->offset + IPFIX_HDR_BYTES );
       INSERTU32( buf->buf+buf->buflen, buf->buflen, ts.tv_sec);
       INSERTU32( buf->buf+buf->buflen, buf->buflen, if_h->seqno );
       INSERTU32( buf->buf+buf->buflen, buf->buflen, if_h->sid );

       return 0;
}

#define INSERTU16(b,l,val) \
       { uint16_t _t=htons((val)); memcpy((b),&_t,2); (l)+=2; }

#define INSERTU32(b,l,val) \
       { uint32_t _t=htonl((val)); memcpy((b),&_t,4); (l)+=4; }


If you need something else, just tell me. I also can share code of whole project (~80-100kb patch).


Also it seems that problem only happens at SMP systems. No crashes at UP.

Maybe there is a race condition...

Yes, I suppose so. My code gets executed in softirq/bh context all the time I'm pretty sure.

Thanks,
-- Alexey.


--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux