Beispiel #1
0
STATIC struct inode *
linvfs_alloc_inode(
	struct super_block	*sb)
{
	vnode_t			*vp;

	vp = (vnode_t *)kmem_cache_alloc(linvfs_inode_cachep, 
                kmem_flags_convert(KM_SLEEP));
	if (!vp)
		return NULL;
	return LINVFS_GET_IP(vp);
}
Beispiel #2
0
static char *
__strdup(const char *str, int flags)
{
	char *ptr;
	int n;

	n = strlen(str);
	ptr = kmalloc(n + 1, kmem_flags_convert(flags));
	if (ptr)
		memcpy(ptr, str, n + 1);

	return (ptr);
}
Beispiel #3
0
char *
kmem_asprintf(const char *fmt, ...)
{
	va_list ap;
	char *ptr;

	do {
		va_start(ap, fmt);
		ptr = kvasprintf(kmem_flags_convert(KM_SLEEP), fmt, ap);
		va_end(ap);
	} while (ptr == NULL);

	return (ptr);
}
Beispiel #4
0
char *
kmem_vasprintf(const char *fmt, va_list ap)
{
	va_list aq;
	char *ptr;

	do {
		va_copy(aq, ap);
		ptr = kvasprintf(kmem_flags_convert(KM_SLEEP), fmt, aq);
		va_end(aq);
	} while (ptr == NULL);

	return (ptr);
}
Beispiel #5
0
struct _buf *
kobj_open_file(const char *name)
{
	struct _buf *file;
	vnode_t *vp;
	int rc;

	file = kmalloc(sizeof(_buf_t), kmem_flags_convert(KM_SLEEP));
	if (file == NULL)
		return ((_buf_t *)-1UL);

	if ((rc = vn_open(name, UIO_SYSSPACE, FREAD, 0644, &vp, 0, 0))) {
		kfree(file);
		return ((_buf_t *)-1UL);
	}

	file->vp = vp;

	return (file);
} /* kobj_open_file() */
Beispiel #6
0
/*
 * General purpose unified implementation of kmem_alloc(). It is an
 * amalgamation of Linux and Illumos allocator design. It should never be
 * exported to ensure that code using kmem_alloc()/kmem_zalloc() remains
 * relatively portable.  Consumers may only access this function through
 * wrappers that enforce the common flags to ensure portability.
 */
inline void *
spl_kmem_alloc_impl(size_t size, int flags, int node)
{
	gfp_t lflags = kmem_flags_convert(flags);
	int use_vmem = 0;
	void *ptr;

	/*
	 * Log abnormally large allocations and rate limit the console output.
	 * Allocations larger than spl_kmem_alloc_warn should be performed
	 * through the vmem_alloc()/vmem_zalloc() interfaces.
	 */
	if ((spl_kmem_alloc_warn > 0) && (size > spl_kmem_alloc_warn) &&
	    !(flags & KM_VMEM)) {
		printk(KERN_WARNING
		    "Large kmem_alloc(%lu, 0x%x), please file an issue at:\n"
		    "https://github.com/zfsonlinux/zfs/issues/new\n",
		    (unsigned long)size, flags);
		dump_stack();
	}

	/*
	 * Use a loop because kmalloc_node() can fail when GFP_KERNEL is used
	 * unlike kmem_alloc() with KM_SLEEP on Illumos.
	 */
	do {
		/*
		 * Calling kmalloc_node() when the size >= spl_kmem_alloc_max
		 * is unsafe.  This must fail for all for kmem_alloc() and
		 * kmem_zalloc() callers.
		 *
		 * For vmem_alloc() and vmem_zalloc() callers it is permissible
		 * to use __vmalloc().  However, in general use of __vmalloc()
		 * is strongly discouraged because a global lock must be
		 * acquired.  Contention on this lock can significantly
		 * impact performance so frequently manipulating the virtual
		 * address space is strongly discouraged.
		 */
		if ((size > spl_kmem_alloc_max) || use_vmem) {
			if (flags & KM_VMEM) {
				ptr = __vmalloc(size, lflags, PAGE_KERNEL);
			} else {
				return (NULL);
			}
		} else {
			ptr = kmalloc_node(size, lflags, node);
		}

		if (likely(ptr) || (flags & KM_NOSLEEP))
			return (ptr);

		/*
		 * For vmem_alloc() and vmem_zalloc() callers retry immediately
		 * using __vmalloc() which is unlikely to fail.
		 */
		if ((flags & KM_VMEM) && (use_vmem == 0))  {
			use_vmem = 1;
			continue;
		}

		/*
		 * Use cond_resched() instead of congestion_wait() to avoid
		 * deadlocking systems where there are no block devices.
		 */
		cond_resched();
	} while (1);

	return (NULL);
}