mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-01-13 03:30:34 +03:00
Stack usage is my enemy. Trade cpu cycles in the debug code to
ensure I never add anything to the stack I don't absolutely need. All this debug code could be removed from a production build anyway so I'm not so worried about the performance impact. We may also consider revisting the mutex and condvar implementation to ensure no additional stack is used there. Initial indications are I have reduced the worst case stack usage to 9080 bytes. Still to large for the default 8k stacks so I have been forced to run with 16k stacks until I can reduce the worst offenders. git-svn-id: https://outreach.scidac.gov/svn/spl/trunk@83 7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c
This commit is contained in:
parent
7fea96c04f
commit
b831734a43
@ -169,25 +169,26 @@ struct page_collection {
|
|||||||
(THREAD_SIZE - 1)))
|
(THREAD_SIZE - 1)))
|
||||||
# endif /* __ia64__ */
|
# endif /* __ia64__ */
|
||||||
|
|
||||||
/* DL_NOTHREAD and DL_SINGLE_CPU flags are passed to spl_debug_bug()
|
/* DL_SINGLE_CPU flag is passed to spl_debug_bug() because we are about
|
||||||
* because we have over run our stack and likely damaged at least one
|
* to over run our stack and likely damage at least one other unknown
|
||||||
* other unknown threads stack. We must finish generating the needed
|
* thread stack. We must finish generating the needed debug info within
|
||||||
* debug info within this thread context because once we yeild the CPU
|
* this thread context because once we yeild the CPU its very likely
|
||||||
* its very likely the system will crash.
|
* the system will crash.
|
||||||
*/
|
*/
|
||||||
#define __CHECK_STACK(file, func, line) \
|
#define __CHECK_STACK(file, func, line) \
|
||||||
do { \
|
do { \
|
||||||
unsigned long _stack = CDEBUG_STACK(); \
|
if (unlikely(CDEBUG_STACK() > spl_debug_stack)) { \
|
||||||
unsigned long _soft_limit = (8 * THREAD_SIZE) / 10; \
|
spl_debug_stack = CDEBUG_STACK(); \
|
||||||
\
|
\
|
||||||
if (unlikely(_stack > _soft_limit && _stack > spl_debug_stack)){\
|
if (unlikely(CDEBUG_STACK() > (4 * THREAD_SIZE) / 5)) { \
|
||||||
spl_debug_stack = _stack; \
|
|
||||||
spl_debug_msg(NULL, D_TRACE, D_WARNING, \
|
spl_debug_msg(NULL, D_TRACE, D_WARNING, \
|
||||||
file, func, line, "Error exceeded " \
|
file, func, line, "Error " \
|
||||||
"maximum safe stack size (%lu/%lu)\n", \
|
"exceeded maximum safe stack " \
|
||||||
_stack, THREAD_SIZE); \
|
"size (%lu/%lu)\n", \
|
||||||
|
CDEBUG_STACK(), THREAD_SIZE); \
|
||||||
spl_debug_bug(file, func, line, DL_SINGLE_CPU); \
|
spl_debug_bug(file, func, line, DL_SINGLE_CPU); \
|
||||||
} \
|
} \
|
||||||
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define CHECK_STACK() __CHECK_STACK(__FILE__, __func__, __LINE__)
|
#define CHECK_STACK() __CHECK_STACK(__FILE__, __func__, __LINE__)
|
||||||
@ -196,7 +197,7 @@ do { \
|
|||||||
#define __ASSERT(cond) \
|
#define __ASSERT(cond) \
|
||||||
do { \
|
do { \
|
||||||
if (unlikely(!(cond))) { \
|
if (unlikely(!(cond))) { \
|
||||||
printk(KERN_ERR "ASSERTION("#cond") failed"); \
|
printk(KERN_ERR "ASSERTION(" #cond ") failed"); \
|
||||||
SBUG(); \
|
SBUG(); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -237,16 +238,13 @@ do { \
|
|||||||
|
|
||||||
#define VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE, FMT, CAST) \
|
#define VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE, FMT, CAST) \
|
||||||
do { \
|
do { \
|
||||||
const TYPE __left = (TYPE)(LEFT); \
|
|
||||||
const TYPE __right = (TYPE)(RIGHT); \
|
|
||||||
\
|
|
||||||
CHECK_STACK(); \
|
CHECK_STACK(); \
|
||||||
\
|
\
|
||||||
if (!(__left OP __right)) { \
|
if (!((TYPE)(LEFT) OP (TYPE)(RIGHT))) { \
|
||||||
spl_debug_msg(NULL, DEBUG_SUBSYSTEM, D_EMERG, \
|
spl_debug_msg(NULL, DEBUG_SUBSYSTEM, D_EMERG, \
|
||||||
__FILE__, __FUNCTION__, __LINE__, \
|
__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"VERIFY3(" FMT " " #OP " " FMT ")\n", \
|
"VERIFY3(" FMT " " #OP " " FMT ")\n", \
|
||||||
CAST __left, CAST __right); \
|
CAST (LEFT), CAST (RIGHT)); \
|
||||||
SBUG(); \
|
SBUG(); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -142,8 +142,9 @@ typedef struct modldrv {
|
|||||||
#define mod_driverops NULL
|
#define mod_driverops NULL
|
||||||
#define ddi_prop_op NULL
|
#define ddi_prop_op NULL
|
||||||
|
|
||||||
#define getminor MINOR
|
#define getminor(x) (x)
|
||||||
#define getmajor MAJOR
|
#define getmajor(x) (x)
|
||||||
|
#define ddi_driver_major(di) getmajor(di->di_dev)
|
||||||
|
|
||||||
#define mod_install(x) 0
|
#define mod_install(x) 0
|
||||||
#define mod_remove(x) 0
|
#define mod_remove(x) 0
|
||||||
@ -158,12 +159,6 @@ extern int __mod_remove(struct modlinkage *modlp);
|
|||||||
static __inline__ void ddi_report_dev(dev_info_t *d) { }
|
static __inline__ void ddi_report_dev(dev_info_t *d) { }
|
||||||
static __inline__ void ddi_prop_remove_all(dev_info_t *dip) { }
|
static __inline__ void ddi_prop_remove_all(dev_info_t *dip) { }
|
||||||
|
|
||||||
static __inline__ major_t
|
|
||||||
ddi_driver_major(dev_info_t *di)
|
|
||||||
{
|
|
||||||
return getmajor(di->di_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ int
|
static __inline__ int
|
||||||
ddi_create_minor_node(dev_info_t *di, char *name, int spec_type,
|
ddi_create_minor_node(dev_info_t *di, char *name, int spec_type,
|
||||||
minor_t minor_num, char *node_type, int flag)
|
minor_t minor_num, char *node_type, int flag)
|
||||||
|
Loading…
Reference in New Issue
Block a user