From 0a6fd143fd6d2eaac4c364b1da88bf1ce65618d2 Mon Sep 17 00:00:00 2001 From: behlendo Date: Thu, 3 Apr 2008 16:33:31 +0000 Subject: [PATCH] - Remapped ldi_handle_t to struct block_device * which is much more useful - Added liunx block device headers to sunldi.h - Made __taskq_dispatch safe for interrupt context where it turns out we need to be useing it. - Fixed NULL const/dest bug for kmem slab caches - Places debug __dprintf debugging messages under a spin_lock_irqsave so it's safe to use then in interrupt handlers. For debugging only! git-svn-id: https://outreach.scidac.gov/svn/spl/trunk@64 7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c --- include/sys/sunldi.h | 11 +++++++---- modules/spl/spl-generic.c | 10 ++++++++-- modules/spl/spl-kmem.c | 8 ++++++-- modules/spl/spl-taskq.c | 5 ++--- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/include/sys/sunldi.h b/include/sys/sunldi.h index f473350beb5c..4c9c90d7928d 100644 --- a/include/sys/sunldi.h +++ b/include/sys/sunldi.h @@ -2,6 +2,12 @@ #define _SPL_SUNLDI_H #include +#include +#include +#include +#include + +#define SECTOR_SIZE 512 typedef struct modlinkage { int ml_rev; @@ -17,10 +23,7 @@ typedef struct ldi_ident { dev_t li_dev; } *ldi_ident_t; -typedef struct ldi_handle { - uint_t lh_type; - struct ldi_ident *lh_ident; -} ldi_handle_t; +typedef struct block_device *ldi_handle_t; extern int ldi_ident_from_mod(struct modlinkage *modlp, ldi_ident_t *lip); extern void ldi_ident_release(ldi_ident_t li); diff --git a/modules/spl/spl-generic.c b/modules/spl/spl-generic.c index 3c958f518386..67511cb60e4c 100644 --- a/modules/spl/spl-generic.c +++ b/modules/spl/spl-generic.c @@ -80,13 +80,19 @@ __dprintf(const char *file, const char *func, int line, const char *fmt, ...) { char *sfp, *start, *ptr; struct timeval tv; + unsigned long flags; va_list ap; start = ptr = spl_debug_buffer; sfp = strrchr(file, '/'); do_gettimeofday(&tv); - spin_lock(&spl_debug_lock); + /* XXX: This is particularly bad for performance, but we need to + * disable irqs here or two __dprintf()'s may deadlock on each + * other if one if called from an irq handler. This is yet another + * reason why we really, really, need an internal debug log. + */ + spin_lock_irqsave(&spl_debug_lock, flags); ptr += snprintf(ptr, MAXMSGLEN - 1, "spl: %lu.%06lu:%d:%u:%s:%d:%s(): ", tv.tv_sec, tv.tv_usec, current->pid, @@ -99,7 +105,7 @@ __dprintf(const char *file, const char *func, int line, const char *fmt, ...) va_end(ap); printk("%s", start); - spin_unlock(&spl_debug_lock); + spin_unlock_irqrestore(&spl_debug_lock, flags); } EXPORT_SYMBOL(__dprintf); diff --git a/modules/spl/spl-kmem.c b/modules/spl/spl-kmem.c index 08387d0d851f..1b9eaafe6968 100644 --- a/modules/spl/spl-kmem.c +++ b/modules/spl/spl-kmem.c @@ -117,7 +117,9 @@ kmem_cache_generic_constructor(void *ptr, kmem_cache_t *cache, unsigned long fla kcc = kmem_cache_find_cache_cb(cache); BUG_ON(!kcc); - kcc->kcc_constructor(ptr, kcc->kcc_private, (int)flags); + if (kcc->kcc_constructor) + kcc->kcc_constructor(ptr, kcc->kcc_private, (int)flags); + spin_unlock(&kmem_cache_cb_lock); /* Linux constructor has no return code, silently eat it */ } @@ -134,7 +136,9 @@ kmem_cache_generic_destructor(void *ptr, kmem_cache_t *cache, unsigned long flag BUG_ON(!kcc); /* Solaris destructor takes no flags, silently eat them */ - kcc->kcc_destructor(ptr, kcc->kcc_private); + if (kcc->kcc_destructor) + kcc->kcc_destructor(ptr, kcc->kcc_private); + spin_unlock(&kmem_cache_cb_lock); } diff --git a/modules/spl/spl-taskq.c b/modules/spl/spl-taskq.c index 67db1064bae8..d177af9ce7ce 100644 --- a/modules/spl/spl-taskq.c +++ b/modules/spl/spl-taskq.c @@ -37,12 +37,11 @@ __taskq_dispatch(taskq_t *tq, task_func_t func, void *priv, uint_t flags) taskq_work_wrapper_t *tww; int rc; - - BUG_ON(in_interrupt()); BUG_ON(tq == NULL); BUG_ON(func == NULL); - tww = (taskq_work_wrapper_t *)kmalloc(sizeof(*tww), GFP_KERNEL); + /* Use GFP_ATOMIC since this may be called in interrupt context */ + tww = (taskq_work_wrapper_t *)kmalloc(sizeof(*tww), GFP_ATOMIC); if (!tww) return (taskqid_t)0;