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