I do most of my development on alphas & I just turned some local code
into a loadable kernel module.  It works fine when compiled into the
kernel statically, but fails miserably when loaded into an alpha
kernel as a module.  This alpha is running -current from monday or
so. 

After a day or so of debugging, I decided to run
it on an x86 -- it ran just fine.  I've narrowed the problem down to
one involving optimization and have extracted a simple, reproducable
test case.

When the test module is loaded without optimization (CFLAGS += -g
-O0), it prints the following (which is correct):

&Xmit_completes[2].unused =              0xfffffe00056fd0f0
&Xmit_completes[2].start_sanity =       0xfffffe00056fd0f8
&Xmit_completes[2].send_msg =           0xfffffe00056fd100
&Xmit_completes[2].io_func =            0xfffffe00056fd108
&Xmit_completes[2].arg =                0xfffffe00056fd110
&Xmit_completes[2].end_sanity =         0xfffffe00056fd118
Xmit_completes[2].unused =              0
Xmit_completes[2].start_sanity =        2
Xmit_completes[2].send_msg =            0
Xmit_completes[2].io_func =             0
Xmit_completes[2].arg =                 0
Xmit_completes[2].end_sanity =          -2

With the normal CFLAGS, it prints:

&Xmit_completes[2].unused =              0xfffffe00056fd050
&Xmit_completes[2].start_sanity =       0xfffffe00056fd058
&Xmit_completes[2].send_msg =           0xfffffe00056fd060
&Xmit_completes[2].io_func =            0xfffffe00056fd068
&Xmit_completes[2].arg =                0xfffffe00056fd070
&Xmit_completes[2].end_sanity =         0xfffffe00056fd078
Xmit_completes[2].unused =              -2
Xmit_completes[2].start_sanity =        0
Xmit_completes[2].send_msg =            0
Xmit_completes[2].io_func =             0
Xmit_completes[2].arg =                 0
Xmit_completes[2].end_sanity =          0


If you look at the array in gdb (or print it all) you notice that the
"unused" field has taken all the writes intended for the "end_sanity"
fields, and all the writes intended for "start_sanity" have disappeared.

I'm using the following Makefile to build the module:

.PATH: /usr/project/ari1/users/gallatin/hacks/simple
KMOD =  simple
SRCS += simple.c
CFLAGS += -g 
.include <bsd.kmod.mk>


The module contains the following code:

/**************** start ************************/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>

#define SHMEM_PAYLOAD_SIZE 30
typedef struct _shmem_ctrl_msg 
{
  uint pkt_header;
  uint ctl_length; 
  /* this is all sent as a message */
  uint pkt_length;
  uint gather_length;
  uint pkt_type;
  uint shmem_payload[SHMEM_PAYLOAD_SIZE];
  uint pad;
} ctrl_msg;

typedef void (*io_completion_t)(void *, int, caddr_t);
typedef struct _io_complete
{
  long unused;
  long start_sanity;
  ctrl_msg *send_msg;
  io_completion_t io_func;
  caddr_t arg;
  long end_sanity;
}io_completions;


#define NUM_RING_ENTRIES 128
io_completions Xmit_completes[NUM_RING_ENTRIES];


static void
simple_init(void)
{
        int i;

        printf("&Xmit_completes[2].unused =             %p\n", 
&Xmit_completes[2].unused);
        printf("&Xmit_completes[2].start_sanity =       %p\n", 
&Xmit_completes[2].start_sanity);
        printf("&Xmit_completes[2].send_msg =           %p\n", 
&Xmit_completes[2].send_msg);
        printf("&Xmit_completes[2].io_func =            %p\n", 
&Xmit_completes[2].io_func);
        printf("&Xmit_completes[2].arg =                %p\n", &Xmit_completes[2].arg);
        printf("&Xmit_completes[2].end_sanity =         %p\n", 
&Xmit_completes[2].end_sanity);

        bzero(Xmit_completes, NUM_RING_ENTRIES*sizeof(io_completions));
        
        for (i = 0; i < NUM_RING_ENTRIES; i++){
            Xmit_completes[i].io_func = NULL;
            Xmit_completes[i].send_msg = NULL;
            Xmit_completes[i].start_sanity = (long)i;
            Xmit_completes[i].end_sanity = -1LL*(long)i;
        }

        printf("Xmit_completes[2].unused =              %ld\n", 
Xmit_completes[2].unused);
        printf("Xmit_completes[2].start_sanity =        %ld\n", 
Xmit_completes[2].start_sanity);
        printf("Xmit_completes[2].send_msg =            %p\n", 
Xmit_completes[2].send_msg);
        printf("Xmit_completes[2].io_func =             %p\n", 
Xmit_completes[2].io_func);
        printf("Xmit_completes[2].arg =                 %p\n", Xmit_completes[2].arg);
        printf("Xmit_completes[2].end_sanity =          %ld\n", 
Xmit_completes[2].end_sanity);
        
}


static int
simple_modevent(module_t mod, int type, void *unused) 
{
        switch (type) {
        case MOD_LOAD:
                /* load */
                simple_init();
                break;
        case MOD_UNLOAD:
                /* unload */
                break;
        default:
                break;
        }
        return 0;               
}
moduledata_t simple_mod = {"simple", simple_modevent, 0};
DECLARE_MODULE(simple, simple_mod, SI_SUB_DRIVERS, SI_ORDER_ANY);
/************ end **********************/



Any help would be appreciated.  I'm currently trying to see if the
problem occurs in egcs 2.95 (from ports).  But it currently doesn't
build.. 

Thanks, 

Drew

------------------------------------------------------------------------------
Andrew Gallatin, Sr Systems Programmer  http://www.cs.duke.edu/~gallatin
Duke University                         Email: [EMAIL PROTECTED]
Department of Computer Science          Phone: (919) 660-6590




To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to