All of lore.kernel.org
 help / color / mirror / Atom feed
From: mcatos@ics.forth.gr
To: linux-kernel@vger.kernel.org
Subject: Error using the buffer cache
Date: Thu,  3 May 2007 15:36:42 +0300	[thread overview]
Message-ID: <1178195802.4639d75ac39fb@webmail.ics.forth.gr> (raw)

[-- Attachment #1: Type: text/plain, Size: 469 bytes --]



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/

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: disk_cache.c --]
[-- Type: text/x-csrc; name="disk_cache.c", Size: 4332 bytes --]

/*
 * 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);


             reply	other threads:[~2007-05-03 13:32 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-03 12:36 mcatos [this message]
  -- strict thread matches above, loose matches on Subject: below --
2007-05-03 13:03 Error using the buffer cache Thanos Makatos
2007-05-04 16:35 mcatos

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1178195802.4639d75ac39fb@webmail.ics.forth.gr \
    --to=mcatos@ics.forth.gr \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.