mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-22 05:01:27 +00:00
kmem_cache_destroy() can handle NULL pointer correctly, so there is no need
to check NULL pointer before calling kmem_cache_destroy().
For kernel versions before v4.3 there is a backport of
kmem_cache_destroy() that checks for a null pointer.
This patch fixes the following checkpatch warnings:
WARNING:NEEDLESS_IF: kmem_cache_destroy(NULL) is safe and this check
is probably not required
196 lines
5.0 KiB
C
196 lines
5.0 KiB
C
/*
|
|
* isert_global.c
|
|
*
|
|
* This file is part of iser target kernel module.
|
|
*
|
|
* Copyright (c) 2013 - 2014 Mellanox Technologies. All rights reserved.
|
|
* Copyright (c) 2013 - 2014 Yan Burman (yanb@mellanox.com)
|
|
*
|
|
* This software is available to you under a choice of one of two
|
|
* licenses. You may choose to be licensed under the terms of the GNU
|
|
* General Public License (GPL) Version 2, available from the file
|
|
* COPYING in the main directory of this source tree, or the
|
|
* OpenIB.org BSD license below:
|
|
*
|
|
* Redistribution and use in source and binary forms, with or
|
|
* without modification, are permitted provided that the following
|
|
* conditions are met:
|
|
*
|
|
* - Redistributions of source code must retain the above
|
|
* copyright notice, this list of conditions and the following
|
|
* disclaimer.
|
|
*
|
|
* - Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following
|
|
* disclaimer in the documentation and/or other materials
|
|
* provided with the distribution.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include "isert_dbg.h"
|
|
#include "iser.h"
|
|
|
|
static struct isert_global isert_glob;
|
|
|
|
struct kmem_cache *isert_cmnd_cache;
|
|
struct kmem_cache *isert_conn_cache;
|
|
|
|
void isert_portal_list_add(struct isert_portal *portal)
|
|
{
|
|
spin_lock(&isert_glob.portal_lock);
|
|
list_add_tail(&portal->list_node, &isert_glob.portal_list);
|
|
isert_glob.portal_cnt++;
|
|
spin_unlock(&isert_glob.portal_lock);
|
|
}
|
|
|
|
void isert_portal_list_remove(struct isert_portal *portal)
|
|
{
|
|
spin_lock(&isert_glob.portal_lock);
|
|
list_del_init(&portal->list_node);
|
|
spin_unlock(&isert_glob.portal_lock);
|
|
}
|
|
|
|
void isert_decrease_portal_cnt(void)
|
|
{
|
|
int portal_cnt;
|
|
|
|
spin_lock(&isert_glob.portal_lock);
|
|
WARN_ON_ONCE(isert_glob.portal_cnt <= 0);
|
|
portal_cnt = --isert_glob.portal_cnt;
|
|
spin_unlock(&isert_glob.portal_lock);
|
|
|
|
if (portal_cnt == 0)
|
|
wake_up_all(&isert_glob.portal_wq);
|
|
}
|
|
|
|
static int isert_portal_cnt(void)
|
|
{
|
|
int portal_cnt;
|
|
|
|
spin_lock(&isert_glob.portal_lock);
|
|
portal_cnt = isert_glob.portal_cnt;
|
|
spin_unlock(&isert_glob.portal_lock);
|
|
|
|
return portal_cnt;
|
|
}
|
|
|
|
void isert_wait_for_portal_release(void)
|
|
{
|
|
wait_event(isert_glob.portal_wq, isert_portal_cnt() == 0);
|
|
}
|
|
|
|
void isert_dev_list_add(struct isert_device *isert_dev)
|
|
{
|
|
list_add_tail(&isert_dev->devs_node, &isert_glob.dev_list);
|
|
}
|
|
|
|
void isert_dev_list_remove(struct isert_device *isert_dev)
|
|
{
|
|
list_del_init(&isert_dev->devs_node);
|
|
}
|
|
|
|
struct isert_device *isert_device_find(struct ib_device *ib_dev)
|
|
{
|
|
struct isert_device *isert_dev;
|
|
struct isert_device *res = NULL;
|
|
|
|
list_for_each_entry(isert_dev, &isert_glob.dev_list, devs_node) {
|
|
if (isert_dev->ib_dev == ib_dev) {
|
|
res = isert_dev;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
void isert_portal_list_release_all(void)
|
|
{
|
|
struct isert_portal *portal, *n;
|
|
|
|
list_for_each_entry_safe(portal, n, &isert_glob.portal_list, list_node)
|
|
isert_portal_release(portal);
|
|
isert_wait_for_portal_release();
|
|
}
|
|
|
|
void isert_conn_queue_work(struct work_struct *w)
|
|
{
|
|
queue_work(isert_glob.conn_wq, w);
|
|
}
|
|
|
|
int isert_global_init(void)
|
|
{
|
|
isert_glob.portal_cnt = 0;
|
|
|
|
INIT_LIST_HEAD(&isert_glob.portal_list);
|
|
INIT_LIST_HEAD(&isert_glob.dev_list);
|
|
|
|
spin_lock_init(&isert_glob.portal_lock);
|
|
init_waitqueue_head(&isert_glob.portal_wq);
|
|
|
|
isert_glob.conn_wq = create_workqueue("isert_conn_wq");
|
|
if (!isert_glob.conn_wq) {
|
|
PRINT_ERROR("Failed to alloc iser conn work queue");
|
|
return -ENOMEM;
|
|
}
|
|
|
|
isert_cmnd_cache = KMEM_CACHE_USERCOPY(isert_cmnd,
|
|
SCST_SLAB_FLAGS|SLAB_HWCACHE_ALIGN,
|
|
iscsi);
|
|
if (!isert_cmnd_cache) {
|
|
destroy_workqueue(isert_glob.conn_wq);
|
|
PRINT_ERROR("Failed to alloc iser command cache");
|
|
return -ENOMEM;
|
|
}
|
|
|
|
isert_conn_cache = KMEM_CACHE(isert_conn,
|
|
SCST_SLAB_FLAGS|SLAB_HWCACHE_ALIGN);
|
|
if (!isert_conn_cache) {
|
|
destroy_workqueue(isert_glob.conn_wq);
|
|
kmem_cache_destroy(isert_cmnd_cache);
|
|
PRINT_ERROR("Failed to alloc iser connection cache");
|
|
return -ENOMEM;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void isert_global_cleanup(void)
|
|
{
|
|
isert_portal_list_release_all();
|
|
if (isert_glob.conn_wq)
|
|
destroy_workqueue(isert_glob.conn_wq);
|
|
kmem_cache_destroy(isert_cmnd_cache);
|
|
kmem_cache_destroy(isert_conn_cache);
|
|
}
|
|
|
|
int isert_get_addr_size(struct sockaddr *sa, size_t *addr_len)
|
|
{
|
|
int ret = 0;
|
|
|
|
switch (sa->sa_family) {
|
|
case AF_INET:
|
|
*addr_len = sizeof(struct sockaddr_in);
|
|
break;
|
|
case AF_INET6:
|
|
*addr_len = sizeof(struct sockaddr_in6);
|
|
break;
|
|
default:
|
|
PRINT_ERROR("Unknown address family");
|
|
ret = -EINVAL;
|
|
goto out;
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|