Re: Error using the buffer cache

2007-05-04 Thread mcatos
I have isolated the problem a little bit. Here's what I do:

struct buffer_head *bh;
sector_t sector = 0;
bh = __bread(bdev, sector, bdev_get_queue(bdev)->hardsect_size);
brelse(bh);
sector++;
bh = __bread(bdev, sector, bdev_get_queue(bdev)->hardsect_size);
brelse(bh);

And I get this error:

BUG: soft lockup detected on CPU#1!
[] show_trace_log_lvl+0x185/0x1a0
[] show_trace+0x12/0x20
[] dump_stack+0x19/0x20
[] softlockup_tick+0x9e/0xd0
[] run_local_timers+0x12/0x20
[] update_process_times+0x34/0x80
[] smp_apic_timer_interrupt+0x6d/0x80
[] apic_timer_interrupt+0x2a/0x30
[] _read_unlock_irq+0x24/0x30
DWARF2 unwinder stuck at _read_unlock_irq+0x24/0x30
Leftover inexact backtrace:
[] show_trace+0x12/0x20
[] dump_stack+0x19/0x20
[] softlockup_tick+0x9e/0xd0
[] run_local_timers+0x12/0x20
[] update_process_times+0x34/0x80
[] smp_apic_timer_interrupt+0x6d/0x80
[] apic_timer_interrupt+0x2a/0x30
[] find_lock_page+0x85/0xa0
[] find_or_create_page+0x3b/0xb0
[] __getblk+0xef/0x2e0
[] __bread+0x12/0xb0

What am I doing wrong?



-
This mail sent through IMP: http://horde.org/imp/

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Error using the buffer cache

2007-05-04 Thread mcatos
I have isolated the problem a little bit. Here's what I do:

struct buffer_head *bh;
sector_t sector = 0;
bh = __bread(bdev, sector, bdev_get_queue(bdev)-hardsect_size);
brelse(bh);
sector++;
bh = __bread(bdev, sector, bdev_get_queue(bdev)-hardsect_size);
brelse(bh);

And I get this error:

BUG: soft lockup detected on CPU#1!
[] show_trace_log_lvl+0x185/0x1a0
[] show_trace+0x12/0x20
[] dump_stack+0x19/0x20
[] softlockup_tick+0x9e/0xd0
[] run_local_timers+0x12/0x20
[] update_process_times+0x34/0x80
[] smp_apic_timer_interrupt+0x6d/0x80
[] apic_timer_interrupt+0x2a/0x30
[] _read_unlock_irq+0x24/0x30
DWARF2 unwinder stuck at _read_unlock_irq+0x24/0x30
Leftover inexact backtrace:
[] show_trace+0x12/0x20
[] dump_stack+0x19/0x20
[] softlockup_tick+0x9e/0xd0
[] run_local_timers+0x12/0x20
[] update_process_times+0x34/0x80
[] smp_apic_timer_interrupt+0x6d/0x80
[] apic_timer_interrupt+0x2a/0x30
[] find_lock_page+0x85/0xa0
[] find_or_create_page+0x3b/0xb0
[] __getblk+0xef/0x2e0
[] __bread+0x12/0xb0

What am I doing wrong?



-
This mail sent through IMP: http://horde.org/imp/

-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Error using the buffer cache

2007-05-03 Thread Thanos Makatos
I've written a module that acts as a cache for fixed size objects but I
get a soft lockup trying to use the buffer cache.

I've attached the module that reproduces the error. You need to supply the
module with a block device, i.e.
insmod disk_cache.ko devname="/dev/hda2".
/*
 * An object oriented disk cache.
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
//#include "assert.h"
//#include "debug.h"
#define assert(s) if(!(s)) { printk(KERN_EMERG "assertion failed: %d: ", 
__LINE__); panic(#s);}

#define KERNEL_SECTOR_SIZE 512

MODULE_LICENSE("Dual BSD/GPL");

struct disk_cache {
int object_size;/* object size */
sector_t cache_size;/* number of objects to be held 
in cache */
sector_t disk_size; /* maximum number of objects */
int objects_per_sector; /* number of objects per sector 
*/
sector_t start; /* start sector for data 
storage */
};

static int major_num = 0;

struct block_device *bdev = NULL;

sector_t start = 0;

static char *devname = NULL;
module_param(devname, charp, 0);

/*
 * Create and initialize a disk cache.
 * @disk_cache - an allocated disk_cache structure
 * @object_size - the object size to use (in bytes)
 * @cache_size - total memory size for cache (in objects)
 * @disk_size - total disk size for objects (in objects)
 */
int disk_cache_create(struct disk_cache* const disk_cache, const int 
object_size, const sector_t disk_size) {

assert(disk_cache);
assert(disk_size > 0);

disk_cache->object_size = object_size;
disk_cache->disk_size = disk_size;
disk_cache->objects_per_sector = bdev_get_queue(bdev)->hardsect_size / 
object_size;
disk_cache->start = start;  
start += ((unsigned long)disk_size / (unsigned 
long)disk_cache->objects_per_sector) + 1;
return 1;
}
EXPORT_SYMBOL(disk_cache_create);

/*
 * Returns an address where the requested object is found.
 */
void * get_object(const struct disk_cache* disk_cache, const sector_t 
object_number) {

int offset = 0;
sector_t sector = 0;
struct buffer_head *bh = NULL;

assert(disk_cache);
assert(object_number < disk_cache->disk_size);

/*
 * Compute page number in which requested object resides.
 */
sector = disk_cache->start + (unsigned long)object_number / (unsigned 
long)disk_cache->objects_per_sector;
//assert(sector < disk_cache->disk_size);
//assert(sector < get_capacity(bdev->bd_disk));
offset = ((unsigned long)object_number % (unsigned 
long)disk_cache->objects_per_sector) * disk_cache->object_size;

bh = __bread(bdev, sector, bdev_get_queue(bdev)->hardsect_size);
//return bh->b_data + offset;
return NULL;
}
EXPORT_SYMBOL(get_object);

/*
 * Puts given object back to the buffer cache. Flag 'modified' must be set if 
the object was modified.
 */
void put_object(const struct disk_cache* const disk_cache, const sector_t 
object_number, const int modified) {

struct buffer_head *bh = NULL;
sector_t sector = disk_cache->start + (unsigned long)object_number / 
(unsigned long)disk_cache->objects_per_sector;

bh = __bread(bdev, sector, bdev_get_queue(bdev)->hardsect_size);
//if(modified) {
//  lock_buffer(bh);
//  set_buffer_uptodate(bh);
//  mark_buffer_dirty(bh);
//  unlock_buffer(bh);
//}
brelse(bh);
/*
 * an additional release, we didn't released it in get_object
 */
brelse(bh); 
}
EXPORT_SYMBOL(put_object);

static void test(void) {

struct disk_cache dk;
int i;
void *p;

if(!disk_cache_create(, 6, 100)) {
printk(KERN_ERR "create cache error\n");
return;
}
for(i = 0; i < 100; i++) {
get_object(, i);
put_object(, i, 0);
}
}

static int __init disk_cache_init(void) {

major_num = register_blkdev(major_num, "disk_cache");
if (major_num <= 0) {
printk(KERN_ERR "disk_cache: unable to get major number\n");
return -EINVAL;
}

if(!devname) {
printk(KERN_ERR "disk_cache: must supply a valid block 
device\n");
return -EINVAL;
}

bdev = open_bdev_excl(devname, 0, NULL);
if(IS_ERR(bdev)) {
printk(KERN_ERR "disk_cache: cannot open device %s.\n", 
devname);
return -EINVAL;
}

printk(KERN_INFO "disk_cache: using device %s\n", devname);
printk(KERN_INFO "disk_cache: %llu sectors\n", 
get_capacity(bdev->bd_disk));

test();

return 0;
}

static void 

Error using the buffer cache

2007-05-03 Thread mcatos


I've written a module that acts as a cache for fixed size objects but I'm
getting a soft lockup using the buffer cache as backing storage.

I've attached the code that reproduces the error. You need to supply the module
with a valid block device, i.e. insmod disk_cache.ko devname="/dev/hda2".

Thanx.

P.S: It's the first time I'm writing here, please be gentle...

-
This mail sent through IMP: http://horde.org/imp/
/*
 * An object oriented disk cache.
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
//#include "assert.h"
//#include "debug.h"
#define assert(s) if(!(s)) { printk(KERN_EMERG "assertion failed: %d: ", __LINE__); panic(#s);}

#define KERNEL_SECTOR_SIZE 512

MODULE_LICENSE("Dual BSD/GPL");

struct disk_cache {
	int object_size;			/* object size */
	sector_t cache_size;			/* number of objects to be held in cache */
	sector_t disk_size;			/* maximum number of objects */
	int objects_per_sector;			/* number of objects per sector */
	sector_t start;/* start sector for data storage */
};

static int major_num = 0;

struct block_device *bdev = NULL;

sector_t start = 0;

static char *devname = NULL;
module_param(devname, charp, 0);

/*
 * Create and initialize a disk cache.
 * @disk_cache - an allocated disk_cache structure
 * @object_size - the object size to use (in bytes)
 * @cache_size - total memory size for cache (in objects)
 * @disk_size - total disk size for objects (in objects)
 */
int disk_cache_create(struct disk_cache* const disk_cache, const int object_size, const sector_t disk_size) {

	assert(disk_cache);
	assert(disk_size > 0);
	
	disk_cache->object_size = object_size;
	disk_cache->disk_size = disk_size;
	disk_cache->objects_per_sector = bdev_get_queue(bdev)->hardsect_size / object_size;
	disk_cache->start = start;	
	start += ((unsigned long)disk_size / (unsigned long)disk_cache->objects_per_sector) + 1;
	return 1;
}
EXPORT_SYMBOL(disk_cache_create);

/*
 * Returns an address where the requested object is found.
 */
void * get_object(const struct disk_cache* disk_cache, const sector_t object_number) {

	int offset = 0;
	sector_t sector = 0;
	struct buffer_head *bh = NULL;

	assert(disk_cache);
	assert(object_number < disk_cache->disk_size);

	/*
	 * Compute page number in which requested object resides.
	 */
	sector = disk_cache->start + (unsigned long)object_number / (unsigned long)disk_cache->objects_per_sector;
	//assert(sector < disk_cache->disk_size);
	//assert(sector < get_capacity(bdev->bd_disk));
	offset = ((unsigned long)object_number % (unsigned long)disk_cache->objects_per_sector) * disk_cache->object_size;

	bh = __bread(bdev, sector, bdev_get_queue(bdev)->hardsect_size);
	//return bh->b_data + offset;
	return NULL;
}
EXPORT_SYMBOL(get_object);

/*
 * Puts given object back to the buffer cache. Flag 'modified' must be set if the object was modified.
 */
void put_object(const struct disk_cache* const disk_cache, const sector_t object_number, const int modified) {

	struct buffer_head *bh = NULL;
	sector_t sector = disk_cache->start + (unsigned long)object_number / (unsigned long)disk_cache->objects_per_sector;
	
	bh = __bread(bdev, sector, bdev_get_queue(bdev)->hardsect_size);
	//if(modified) {		
	//	lock_buffer(bh);
	//	set_buffer_uptodate(bh);
	//	mark_buffer_dirty(bh);
	//	unlock_buffer(bh);
	//}
	brelse(bh);
	/*
	 * an additional release, we didn't released it in get_object
	 */
	brelse(bh);		
}
EXPORT_SYMBOL(put_object);

static void test(void) {

	struct disk_cache dk;
	int i;
	void *p;

	if(!disk_cache_create(, 6, 100)) {
		printk(KERN_ERR "create cache error\n");
		return;
	}
	for(i = 0; i < 100; i++) {
		get_object(, i);
		put_object(, i, 0);
	}
}

static int __init disk_cache_init(void) {

	major_num = register_blkdev(major_num, "disk_cache");
	if (major_num <= 0) {
		printk(KERN_ERR "disk_cache: unable to get major number\n");
		return -EINVAL;
	}

	if(!devname) {
		printk(KERN_ERR "disk_cache: must supply a valid block device\n");
		return -EINVAL;
	}

	bdev = open_bdev_excl(devname, 0, NULL);
	if(IS_ERR(bdev)) {
		printk(KERN_ERR "disk_cache: cannot open device %s.\n", devname);
		return -EINVAL;
	}

	printk(KERN_INFO "disk_cache: using device %s\n", devname);
	printk(KERN_INFO "disk_cache: %llu sectors\n", get_capacity(bdev->bd_disk));

	test();
	
	return 0;
}

static void __exit disk_cache_exit(void) {
	close_bdev_excl(bdev);
}

module_init(disk_cache_init);
module_exit(disk_cache_exit);



Error using the buffer cache

2007-05-03 Thread mcatos


I've written a module that acts as a cache for fixed size objects but I'm
getting a soft lockup using the buffer cache as backing storage.

I've attached the code that reproduces the error. You need to supply the module
with a valid block device, i.e. insmod disk_cache.ko devname=/dev/hda2.

Thanx.

P.S: It's the first time I'm writing here, please be gentle...

-
This mail sent through IMP: http://horde.org/imp/
/*
 * An object oriented disk cache.
 */

#include linux/module.h
#include linux/moduleparam.h
#include linux/init.h
#include linux/kernel.h
#include linux/fs.h
#include linux/errno.h
#include linux/types.h
#include linux/vmalloc.h
#include linux/genhd.h
#include linux/blkdev.h
#include linux/hdreg.h
#include linux/workqueue.h
#include linux/bio.h
#include linux/buffer_head.h
//#include assert.h
//#include debug.h
#define assert(s) if(!(s)) { printk(KERN_EMERG assertion failed: %d: , __LINE__); panic(#s);}

#define KERNEL_SECTOR_SIZE 512

MODULE_LICENSE(Dual BSD/GPL);

struct disk_cache {
	int object_size;			/* object size */
	sector_t cache_size;			/* number of objects to be held in cache */
	sector_t disk_size;			/* maximum number of objects */
	int objects_per_sector;			/* number of objects per sector */
	sector_t start;/* start sector for data storage */
};

static int major_num = 0;

struct block_device *bdev = NULL;

sector_t start = 0;

static char *devname = NULL;
module_param(devname, charp, 0);

/*
 * Create and initialize a disk cache.
 * @disk_cache - an allocated disk_cache structure
 * @object_size - the object size to use (in bytes)
 * @cache_size - total memory size for cache (in objects)
 * @disk_size - total disk size for objects (in objects)
 */
int disk_cache_create(struct disk_cache* const disk_cache, const int object_size, const sector_t disk_size) {

	assert(disk_cache);
	assert(disk_size  0);
	
	disk_cache-object_size = object_size;
	disk_cache-disk_size = disk_size;
	disk_cache-objects_per_sector = bdev_get_queue(bdev)-hardsect_size / object_size;
	disk_cache-start = start;	
	start += ((unsigned long)disk_size / (unsigned long)disk_cache-objects_per_sector) + 1;
	return 1;
}
EXPORT_SYMBOL(disk_cache_create);

/*
 * Returns an address where the requested object is found.
 */
void * get_object(const struct disk_cache* disk_cache, const sector_t object_number) {

	int offset = 0;
	sector_t sector = 0;
	struct buffer_head *bh = NULL;

	assert(disk_cache);
	assert(object_number  disk_cache-disk_size);

	/*
	 * Compute page number in which requested object resides.
	 */
	sector = disk_cache-start + (unsigned long)object_number / (unsigned long)disk_cache-objects_per_sector;
	//assert(sector  disk_cache-disk_size);
	//assert(sector  get_capacity(bdev-bd_disk));
	offset = ((unsigned long)object_number % (unsigned long)disk_cache-objects_per_sector) * disk_cache-object_size;

	bh = __bread(bdev, sector, bdev_get_queue(bdev)-hardsect_size);
	//return bh-b_data + offset;
	return NULL;
}
EXPORT_SYMBOL(get_object);

/*
 * Puts given object back to the buffer cache. Flag 'modified' must be set if the object was modified.
 */
void put_object(const struct disk_cache* const disk_cache, const sector_t object_number, const int modified) {

	struct buffer_head *bh = NULL;
	sector_t sector = disk_cache-start + (unsigned long)object_number / (unsigned long)disk_cache-objects_per_sector;
	
	bh = __bread(bdev, sector, bdev_get_queue(bdev)-hardsect_size);
	//if(modified) {		
	//	lock_buffer(bh);
	//	set_buffer_uptodate(bh);
	//	mark_buffer_dirty(bh);
	//	unlock_buffer(bh);
	//}
	brelse(bh);
	/*
	 * an additional release, we didn't released it in get_object
	 */
	brelse(bh);		
}
EXPORT_SYMBOL(put_object);

static void test(void) {

	struct disk_cache dk;
	int i;
	void *p;

	if(!disk_cache_create(dk, 6, 100)) {
		printk(KERN_ERR create cache error\n);
		return;
	}
	for(i = 0; i  100; i++) {
		get_object(dk, i);
		put_object(dk, i, 0);
	}
}

static int __init disk_cache_init(void) {

	major_num = register_blkdev(major_num, disk_cache);
	if (major_num = 0) {
		printk(KERN_ERR disk_cache: unable to get major number\n);
		return -EINVAL;
	}

	if(!devname) {
		printk(KERN_ERR disk_cache: must supply a valid block device\n);
		return -EINVAL;
	}

	bdev = open_bdev_excl(devname, 0, NULL);
	if(IS_ERR(bdev)) {
		printk(KERN_ERR disk_cache: cannot open device %s.\n, devname);
		return -EINVAL;
	}

	printk(KERN_INFO disk_cache: using device %s\n, devname);
	printk(KERN_INFO disk_cache: %llu sectors\n, get_capacity(bdev-bd_disk));

	test();
	
	return 0;
}

static void __exit disk_cache_exit(void) {
	close_bdev_excl(bdev);
}

module_init(disk_cache_init);
module_exit(disk_cache_exit);



Error using the buffer cache

2007-05-03 Thread Thanos Makatos
I've written a module that acts as a cache for fixed size objects but I
get a soft lockup trying to use the buffer cache.

I've attached the module that reproduces the error. You need to supply the
module with a block device, i.e.
insmod disk_cache.ko devname=/dev/hda2.
/*
 * An object oriented disk cache.
 */

#include linux/module.h
#include linux/moduleparam.h
#include linux/init.h
#include linux/kernel.h
#include linux/fs.h
#include linux/errno.h
#include linux/types.h
#include linux/vmalloc.h
#include linux/genhd.h
#include linux/blkdev.h
#include linux/hdreg.h
#include linux/workqueue.h
#include linux/bio.h
#include linux/buffer_head.h
//#include assert.h
//#include debug.h
#define assert(s) if(!(s)) { printk(KERN_EMERG assertion failed: %d: , 
__LINE__); panic(#s);}

#define KERNEL_SECTOR_SIZE 512

MODULE_LICENSE(Dual BSD/GPL);

struct disk_cache {
int object_size;/* object size */
sector_t cache_size;/* number of objects to be held 
in cache */
sector_t disk_size; /* maximum number of objects */
int objects_per_sector; /* number of objects per sector 
*/
sector_t start; /* start sector for data 
storage */
};

static int major_num = 0;

struct block_device *bdev = NULL;

sector_t start = 0;

static char *devname = NULL;
module_param(devname, charp, 0);

/*
 * Create and initialize a disk cache.
 * @disk_cache - an allocated disk_cache structure
 * @object_size - the object size to use (in bytes)
 * @cache_size - total memory size for cache (in objects)
 * @disk_size - total disk size for objects (in objects)
 */
int disk_cache_create(struct disk_cache* const disk_cache, const int 
object_size, const sector_t disk_size) {

assert(disk_cache);
assert(disk_size  0);

disk_cache-object_size = object_size;
disk_cache-disk_size = disk_size;
disk_cache-objects_per_sector = bdev_get_queue(bdev)-hardsect_size / 
object_size;
disk_cache-start = start;  
start += ((unsigned long)disk_size / (unsigned 
long)disk_cache-objects_per_sector) + 1;
return 1;
}
EXPORT_SYMBOL(disk_cache_create);

/*
 * Returns an address where the requested object is found.
 */
void * get_object(const struct disk_cache* disk_cache, const sector_t 
object_number) {

int offset = 0;
sector_t sector = 0;
struct buffer_head *bh = NULL;

assert(disk_cache);
assert(object_number  disk_cache-disk_size);

/*
 * Compute page number in which requested object resides.
 */
sector = disk_cache-start + (unsigned long)object_number / (unsigned 
long)disk_cache-objects_per_sector;
//assert(sector  disk_cache-disk_size);
//assert(sector  get_capacity(bdev-bd_disk));
offset = ((unsigned long)object_number % (unsigned 
long)disk_cache-objects_per_sector) * disk_cache-object_size;

bh = __bread(bdev, sector, bdev_get_queue(bdev)-hardsect_size);
//return bh-b_data + offset;
return NULL;
}
EXPORT_SYMBOL(get_object);

/*
 * Puts given object back to the buffer cache. Flag 'modified' must be set if 
the object was modified.
 */
void put_object(const struct disk_cache* const disk_cache, const sector_t 
object_number, const int modified) {

struct buffer_head *bh = NULL;
sector_t sector = disk_cache-start + (unsigned long)object_number / 
(unsigned long)disk_cache-objects_per_sector;

bh = __bread(bdev, sector, bdev_get_queue(bdev)-hardsect_size);
//if(modified) {
//  lock_buffer(bh);
//  set_buffer_uptodate(bh);
//  mark_buffer_dirty(bh);
//  unlock_buffer(bh);
//}
brelse(bh);
/*
 * an additional release, we didn't released it in get_object
 */
brelse(bh); 
}
EXPORT_SYMBOL(put_object);

static void test(void) {

struct disk_cache dk;
int i;
void *p;

if(!disk_cache_create(dk, 6, 100)) {
printk(KERN_ERR create cache error\n);
return;
}
for(i = 0; i  100; i++) {
get_object(dk, i);
put_object(dk, i, 0);
}
}

static int __init disk_cache_init(void) {

major_num = register_blkdev(major_num, disk_cache);
if (major_num = 0) {
printk(KERN_ERR disk_cache: unable to get major number\n);
return -EINVAL;
}

if(!devname) {
printk(KERN_ERR disk_cache: must supply a valid block 
device\n);
return -EINVAL;
}

bdev = open_bdev_excl(devname, 0, NULL);
if(IS_ERR(bdev)) {
printk(KERN_ERR disk_cache: cannot open device %s.\n, 
devname);
return -EINVAL;
}

printk(KERN_INFO disk_cache: using device %s\n,