diff options
Diffstat (limited to 'drivers/xen')
-rw-r--r-- | drivers/xen/Kconfig | 23 | ||||
-rw-r--r-- | drivers/xen/balloon.c | 17 | ||||
-rw-r--r-- | drivers/xen/events/events_2l.c | 6 | ||||
-rw-r--r-- | drivers/xen/events/events_base.c | 8 | ||||
-rw-r--r-- | drivers/xen/events/events_fifo.c | 1 | ||||
-rw-r--r-- | drivers/xen/features.c | 2 | ||||
-rw-r--r-- | drivers/xen/grant-table.c | 1 | ||||
-rw-r--r-- | drivers/xen/platform-pci.c | 22 | ||||
-rw-r--r-- | drivers/xen/sys-hypervisor.c | 59 | ||||
-rw-r--r-- | drivers/xen/xen-balloon.c | 14 | ||||
-rw-r--r-- | drivers/xen/xen-pciback/conf_space.c | 2 | ||||
-rw-r--r-- | drivers/xen/xen-pciback/pciback_ops.c | 2 | ||||
-rw-r--r-- | drivers/xen/xen-pciback/xenbus.c | 2 | ||||
-rw-r--r-- | drivers/xen/xen-scsiback.c | 281 | ||||
-rw-r--r-- | drivers/xen/xen-selfballoon.c | 1 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_dev_backend.c | 13 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_dev_frontend.c | 13 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_xs.c | 1 | ||||
-rw-r--r-- | drivers/xen/xenfs/xensyms.c | 1 |
19 files changed, 201 insertions, 268 deletions
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 73708acce..979a83172 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -37,23 +37,30 @@ config XEN_BALLOON_MEMORY_HOTPLUG Memory could be hotplugged in following steps: - 1) dom0: xl mem-max <domU> <maxmem> + 1) target domain: ensure that memory auto online policy is in + effect by checking /sys/devices/system/memory/auto_online_blocks + file (should be 'online'). + + 2) control domain: xl mem-max <target-domain> <maxmem> where <maxmem> is >= requested memory size, - 2) dom0: xl mem-set <domU> <memory> + 3) control domain: xl mem-set <target-domain> <memory> where <memory> is requested memory size; alternatively memory could be added by writing proper value to /sys/devices/system/xen_memory/xen_memory0/target or - /sys/devices/system/xen_memory/xen_memory0/target_kb on dumU, + /sys/devices/system/xen_memory/xen_memory0/target_kb on the + target domain. - 3) domU: for i in /sys/devices/system/memory/memory*/state; do \ - [ "`cat "$i"`" = offline ] && echo online > "$i"; done + Alternatively, if memory auto onlining was not requested at step 1 + the newly added memory can be manually onlined in the target domain + by doing the following: - Memory could be onlined automatically on domU by adding following line to udev rules: + for i in /sys/devices/system/memory/memory*/state; do \ + [ "`cat "$i"`" = offline ] && echo online > "$i"; done - SUBSYSTEM=="memory", ACTION=="add", RUN+="/bin/sh -c '[ -f /sys$devpath/state ] && echo online > /sys$devpath/state'" + or by adding the following line to udev rules: - In that case step 3 should be omitted. + SUBSYSTEM=="memory", ACTION=="add", RUN+="/bin/sh -c '[ -f /sys$devpath/state ] && echo online > /sys$devpath/state'" config XEN_BALLOON_MEMORY_HOTPLUG_LIMIT int "Hotplugged memory limit (in GiB) for a PV guest" diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 364bc4461..d46839f51 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -42,7 +42,6 @@ #include <linux/kernel.h> #include <linux/sched.h> #include <linux/errno.h> -#include <linux/module.h> #include <linux/mm.h> #include <linux/bootmem.h> #include <linux/pagemap.h> @@ -259,7 +258,7 @@ static struct resource *additional_memory_resource(phys_addr_t size) return NULL; res->name = "System RAM"; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; ret = allocate_resource(&iomem_resource, res, size, 0, -1, @@ -354,7 +353,16 @@ static enum bp_state reserve_additional_memory(void) } #endif - rc = add_memory_resource(nid, resource); + /* + * add_memory_resource() will call online_pages() which in its turn + * will call xen_online_page() callback causing deadlock if we don't + * release balloon_mutex here. Unlocking here is safe because the + * callers drop the mutex before trying again. + */ + mutex_unlock(&balloon_mutex); + rc = add_memory_resource(nid, resource, memhp_auto_online); + mutex_lock(&balloon_mutex); + if (rc) { pr_warn("Cannot add additional memory (%i)\n", rc); goto err; @@ -767,7 +775,4 @@ static int __init balloon_init(void) return 0; } - subsys_initcall(balloon_init); - -MODULE_LICENSE("GPL"); diff --git a/drivers/xen/events/events_2l.c b/drivers/xen/events/events_2l.c index 7dd46312c..bdff01095 100644 --- a/drivers/xen/events/events_2l.c +++ b/drivers/xen/events/events_2l.c @@ -9,7 +9,6 @@ #include <linux/linkage.h> #include <linux/interrupt.h> #include <linux/irq.h> -#include <linux/module.h> #include <asm/sync_bitops.h> #include <asm/xen/hypercall.h> @@ -38,8 +37,9 @@ /* Find the first set bit in a evtchn mask */ #define EVTCHN_FIRST_BIT(w) find_first_bit(BM(&(w)), BITS_PER_EVTCHN_WORD) -static DEFINE_PER_CPU(xen_ulong_t [EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD], - cpu_evtchn_mask); +#define EVTCHN_MASK_SIZE (EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD) + +static DEFINE_PER_CPU(xen_ulong_t [EVTCHN_MASK_SIZE], cpu_evtchn_mask); static unsigned evtchn_2l_max_channels(void) { diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index 44367783f..71d49a95f 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c @@ -26,7 +26,7 @@ #include <linux/linkage.h> #include <linux/interrupt.h> #include <linux/irq.h> -#include <linux/module.h> +#include <linux/moduleparam.h> #include <linux/string.h> #include <linux/bootmem.h> #include <linux/slab.h> @@ -487,7 +487,8 @@ static void eoi_pirq(struct irq_data *data) if (!VALID_EVTCHN(evtchn)) return; - if (unlikely(irqd_is_setaffinity_pending(data))) { + if (unlikely(irqd_is_setaffinity_pending(data)) && + likely(!irqd_irq_disabled(data))) { int masked = test_and_set_mask(evtchn); clear_evtchn(evtchn); @@ -1370,7 +1371,8 @@ static void ack_dynirq(struct irq_data *data) if (!VALID_EVTCHN(evtchn)) return; - if (unlikely(irqd_is_setaffinity_pending(data))) { + if (unlikely(irqd_is_setaffinity_pending(data)) && + likely(!irqd_irq_disabled(data))) { int masked = test_and_set_mask(evtchn); clear_evtchn(evtchn); diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c index eff2b8800..9289a1771 100644 --- a/drivers/xen/events/events_fifo.c +++ b/drivers/xen/events/events_fifo.c @@ -36,7 +36,6 @@ #include <linux/linkage.h> #include <linux/interrupt.h> #include <linux/irq.h> -#include <linux/module.h> #include <linux/smp.h> #include <linux/percpu.h> #include <linux/cpu.h> diff --git a/drivers/xen/features.c b/drivers/xen/features.c index 99eda169c..d7d34fdfc 100644 --- a/drivers/xen/features.c +++ b/drivers/xen/features.c @@ -7,7 +7,7 @@ */ #include <linux/types.h> #include <linux/cache.h> -#include <linux/module.h> +#include <linux/export.h> #include <asm/xen/hypercall.h> diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index effbaf917..bb36b1e1d 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -33,7 +33,6 @@ #define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt -#include <linux/module.h> #include <linux/sched.h> #include <linux/mm.h> #include <linux/slab.h> diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c index 3454973dc..cf9666680 100644 --- a/drivers/xen/platform-pci.c +++ b/drivers/xen/platform-pci.c @@ -2,6 +2,9 @@ * platform-pci.c * * Xen platform PCI device driver + * + * Authors: ssmith@xensource.com and stefano.stabellini@eu.citrix.com + * * Copyright (c) 2005, Intel Corporation. * Copyright (c) 2007, XenSource Inc. * Copyright (c) 2010, Citrix @@ -24,7 +27,7 @@ #include <linux/interrupt.h> #include <linux/io.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/pci.h> #include <xen/platform_pci.h> @@ -36,10 +39,6 @@ #define DRV_NAME "xen-platform-pci" -MODULE_AUTHOR("ssmith@xensource.com and stefano.stabellini@eu.citrix.com"); -MODULE_DESCRIPTION("Xen platform PCI device"); -MODULE_LICENSE("GPL"); - static unsigned long platform_mmio; static unsigned long platform_mmio_alloc; static unsigned long platform_mmiolen; @@ -101,8 +100,8 @@ static int platform_pci_resume(struct pci_dev *pdev) return 0; } -static int platform_pci_init(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int platform_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) { int i, ret; long ioaddr; @@ -181,20 +180,17 @@ static struct pci_device_id platform_pci_tbl[] = { {0,} }; -MODULE_DEVICE_TABLE(pci, platform_pci_tbl); - static struct pci_driver platform_driver = { .name = DRV_NAME, - .probe = platform_pci_init, + .probe = platform_pci_probe, .id_table = platform_pci_tbl, #ifdef CONFIG_PM .resume_early = platform_pci_resume, #endif }; -static int __init platform_pci_module_init(void) +static int __init platform_pci_init(void) { return pci_register_driver(&platform_driver); } - -module_init(platform_pci_module_init); +device_initcall(platform_pci_init); diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c index b5a7342e0..6881b3ceb 100644 --- a/drivers/xen/sys-hypervisor.c +++ b/drivers/xen/sys-hypervisor.c @@ -9,7 +9,7 @@ #include <linux/slab.h> #include <linux/kernel.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/kobject.h> #include <linux/err.h> @@ -50,11 +50,6 @@ static int __init xen_sysfs_type_init(void) return sysfs_create_file(hypervisor_kobj, &type_attr.attr); } -static void xen_sysfs_type_destroy(void) -{ - sysfs_remove_file(hypervisor_kobj, &type_attr.attr); -} - /* xen version attributes */ static ssize_t major_show(struct hyp_sysfs_attr *attr, char *buffer) { @@ -111,11 +106,6 @@ static int __init xen_sysfs_version_init(void) return sysfs_create_group(hypervisor_kobj, &version_group); } -static void xen_sysfs_version_destroy(void) -{ - sysfs_remove_group(hypervisor_kobj, &version_group); -} - /* UUID */ static ssize_t uuid_show_fallback(struct hyp_sysfs_attr *attr, char *buffer) @@ -157,11 +147,6 @@ static int __init xen_sysfs_uuid_init(void) return sysfs_create_file(hypervisor_kobj, &uuid_attr.attr); } -static void xen_sysfs_uuid_destroy(void) -{ - sysfs_remove_file(hypervisor_kobj, &uuid_attr.attr); -} - /* xen compilation attributes */ static ssize_t compiler_show(struct hyp_sysfs_attr *attr, char *buffer) @@ -235,11 +220,6 @@ static int __init xen_compilation_init(void) return sysfs_create_group(hypervisor_kobj, &xen_compilation_group); } -static void xen_compilation_destroy(void) -{ - sysfs_remove_group(hypervisor_kobj, &xen_compilation_group); -} - /* xen properties info */ static ssize_t capabilities_show(struct hyp_sysfs_attr *attr, char *buffer) @@ -366,11 +346,6 @@ static int __init xen_properties_init(void) return sysfs_create_group(hypervisor_kobj, &xen_properties_group); } -static void xen_properties_destroy(void) -{ - sysfs_remove_group(hypervisor_kobj, &xen_properties_group); -} - #ifdef CONFIG_XEN_HAVE_VPMU struct pmu_mode { const char *name; @@ -484,11 +459,6 @@ static int __init xen_pmu_init(void) { return sysfs_create_group(hypervisor_kobj, &xen_pmu_group); } - -static void xen_pmu_destroy(void) -{ - sysfs_remove_group(hypervisor_kobj, &xen_pmu_group); -} #endif static int __init hyper_sysfs_init(void) @@ -517,7 +487,8 @@ static int __init hyper_sysfs_init(void) if (xen_initial_domain()) { ret = xen_pmu_init(); if (ret) { - xen_properties_destroy(); + sysfs_remove_group(hypervisor_kobj, + &xen_properties_group); goto prop_out; } } @@ -525,31 +496,17 @@ static int __init hyper_sysfs_init(void) goto out; prop_out: - xen_sysfs_uuid_destroy(); + sysfs_remove_file(hypervisor_kobj, &uuid_attr.attr); uuid_out: - xen_compilation_destroy(); + sysfs_remove_group(hypervisor_kobj, &xen_compilation_group); comp_out: - xen_sysfs_version_destroy(); + sysfs_remove_group(hypervisor_kobj, &version_group); version_out: - xen_sysfs_type_destroy(); + sysfs_remove_file(hypervisor_kobj, &type_attr.attr); out: return ret; } - -static void __exit hyper_sysfs_exit(void) -{ -#ifdef CONFIG_XEN_HAVE_VPMU - xen_pmu_destroy(); -#endif - xen_properties_destroy(); - xen_compilation_destroy(); - xen_sysfs_uuid_destroy(); - xen_sysfs_version_destroy(); - xen_sysfs_type_destroy(); - -} -module_init(hyper_sysfs_init); -module_exit(hyper_sysfs_exit); +device_initcall(hyper_sysfs_init); static ssize_t hyp_sysfs_show(struct kobject *kobj, struct attribute *attr, diff --git a/drivers/xen/xen-balloon.c b/drivers/xen/xen-balloon.c index 39e7ef8d3..79865b890 100644 --- a/drivers/xen/xen-balloon.c +++ b/drivers/xen/xen-balloon.c @@ -33,7 +33,9 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/kernel.h> -#include <linux/module.h> +#include <linux/errno.h> +#include <linux/mm_types.h> +#include <linux/init.h> #include <linux/capability.h> #include <xen/xen.h> @@ -109,14 +111,6 @@ static int __init balloon_init(void) } subsys_initcall(balloon_init); -static void balloon_exit(void) -{ - /* XXX - release balloon here */ - return; -} - -module_exit(balloon_exit); - #define BALLOON_SHOW(name, format, args...) \ static ssize_t show_##name(struct device *dev, \ struct device_attribute *attr, \ @@ -250,5 +244,3 @@ static int register_balloon(struct device *dev) return 0; } - -MODULE_LICENSE("GPL"); diff --git a/drivers/xen/xen-pciback/conf_space.c b/drivers/xen/xen-pciback/conf_space.c index 9c234209d..8e67336f8 100644 --- a/drivers/xen/xen-pciback/conf_space.c +++ b/drivers/xen/xen-pciback/conf_space.c @@ -10,7 +10,7 @@ */ #include <linux/kernel.h> -#include <linux/module.h> +#include <linux/moduleparam.h> #include <linux/pci.h> #include "pciback.h" #include "conf_space.h" diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c index fb0221434..2f19dd755 100644 --- a/drivers/xen/xen-pciback/pciback_ops.c +++ b/drivers/xen/xen-pciback/pciback_ops.c @@ -6,7 +6,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include <linux/module.h> +#include <linux/moduleparam.h> #include <linux/wait.h> #include <linux/bitops.h> #include <xen/events.h> diff --git a/drivers/xen/xen-pciback/xenbus.c b/drivers/xen/xen-pciback/xenbus.c index 4843741e7..c252eb3f0 100644 --- a/drivers/xen/xen-pciback/xenbus.c +++ b/drivers/xen/xen-pciback/xenbus.c @@ -6,7 +6,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include <linux/module.h> +#include <linux/moduleparam.h> #include <linux/init.h> #include <linux/list.h> #include <linux/vmalloc.h> diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c index c46ee1894..ff932624e 100644 --- a/drivers/xen/xen-scsiback.c +++ b/drivers/xen/xen-scsiback.c @@ -141,6 +141,8 @@ struct scsiback_tmr { wait_queue_head_t tmr_wait; }; +#define VSCSI_DEFAULT_SESSION_TAGS 128 + struct scsiback_nexus { /* Pointer to TCM session for I_T Nexus */ struct se_session *tvn_se_sess; @@ -190,7 +192,6 @@ module_param_named(max_buffer_pages, scsiback_max_buffer_pages, int, 0644); MODULE_PARM_DESC(max_buffer_pages, "Maximum number of free pages to keep in backend buffer"); -static struct kmem_cache *scsiback_cachep; static DEFINE_SPINLOCK(free_pages_lock); static int free_pages_num; static LIST_HEAD(scsiback_free_pages); @@ -321,11 +322,11 @@ static void scsiback_free_translation_entry(struct kref *kref) kfree(entry); } -static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result, - uint32_t resid, struct vscsibk_pend *pending_req) +static void scsiback_send_response(struct vscsibk_info *info, + char *sense_buffer, int32_t result, uint32_t resid, + uint16_t rqid) { struct vscsiif_response *ring_res; - struct vscsibk_info *info = pending_req->info; int notify; struct scsi_sense_hdr sshdr; unsigned long flags; @@ -337,7 +338,7 @@ static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result, info->ring.rsp_prod_pvt++; ring_res->rslt = result; - ring_res->rqid = pending_req->rqid; + ring_res->rqid = rqid; if (sense_buffer != NULL && scsi_normalize_sense(sense_buffer, VSCSIIF_SENSE_BUFFERSIZE, @@ -357,6 +358,13 @@ static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result, if (notify) notify_remote_via_irq(info->irq); +} + +static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result, + uint32_t resid, struct vscsibk_pend *pending_req) +{ + scsiback_send_response(pending_req->info, sense_buffer, result, + resid, pending_req->rqid); if (pending_req->v2p) kref_put(&pending_req->v2p->kref, @@ -380,6 +388,12 @@ static void scsiback_cmd_done(struct vscsibk_pend *pending_req) scsiback_fast_flush_area(pending_req); scsiback_do_resp_with_sense(sense_buffer, errors, resid, pending_req); scsiback_put(info); + /* + * Drop the extra KREF_ACK reference taken by target_submit_cmd_map_sgls() + * ahead of scsiback_check_stop_free() -> transport_generic_free_cmd() + * final se_cmd->cmd_kref put. + */ + target_put_sess_cmd(&pending_req->se_cmd); } static void scsiback_cmd_exec(struct vscsibk_pend *pending_req) @@ -388,16 +402,12 @@ static void scsiback_cmd_exec(struct vscsibk_pend *pending_req) struct se_session *sess = pending_req->v2p->tpg->tpg_nexus->tvn_se_sess; int rc; - memset(pending_req->sense_buffer, 0, VSCSIIF_SENSE_BUFFERSIZE); - - memset(se_cmd, 0, sizeof(*se_cmd)); - scsiback_get(pending_req->info); se_cmd->tag = pending_req->rqid; rc = target_submit_cmd_map_sgls(se_cmd, sess, pending_req->cmnd, pending_req->sense_buffer, pending_req->v2p->lun, pending_req->data_len, 0, - pending_req->sc_data_direction, 0, + pending_req->sc_data_direction, TARGET_SCF_ACK_KREF, pending_req->sgl, pending_req->n_sg, NULL, 0, NULL, 0); if (rc < 0) { @@ -586,45 +596,40 @@ static void scsiback_disconnect(struct vscsibk_info *info) static void scsiback_device_action(struct vscsibk_pend *pending_req, enum tcm_tmreq_table act, int tag) { - int rc, err = FAILED; struct scsiback_tpg *tpg = pending_req->v2p->tpg; + struct scsiback_nexus *nexus = tpg->tpg_nexus; struct se_cmd *se_cmd = &pending_req->se_cmd; struct scsiback_tmr *tmr; + u64 unpacked_lun = pending_req->v2p->lun; + int rc, err = FAILED; tmr = kzalloc(sizeof(struct scsiback_tmr), GFP_KERNEL); - if (!tmr) - goto out; + if (!tmr) { + target_put_sess_cmd(se_cmd); + goto err; + } init_waitqueue_head(&tmr->tmr_wait); - transport_init_se_cmd(se_cmd, tpg->se_tpg.se_tpg_tfo, - tpg->tpg_nexus->tvn_se_sess, 0, DMA_NONE, TCM_SIMPLE_TAG, - &pending_req->sense_buffer[0]); - - rc = core_tmr_alloc_req(se_cmd, tmr, act, GFP_KERNEL); - if (rc < 0) - goto out; - - se_cmd->se_tmr_req->ref_task_tag = tag; - - if (transport_lookup_tmr_lun(se_cmd, pending_req->v2p->lun) < 0) - goto out; + rc = target_submit_tmr(&pending_req->se_cmd, nexus->tvn_se_sess, + &pending_req->sense_buffer[0], + unpacked_lun, tmr, act, GFP_KERNEL, + tag, TARGET_SCF_ACK_KREF); + if (rc) + goto err; - transport_generic_handle_tmr(se_cmd); wait_event(tmr->tmr_wait, atomic_read(&tmr->tmr_complete)); err = (se_cmd->se_tmr_req->response == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED; -out: - if (tmr) { - transport_generic_free_cmd(&pending_req->se_cmd, 1); + scsiback_do_resp_with_sense(NULL, err, 0, pending_req); + transport_generic_free_cmd(&pending_req->se_cmd, 1); + return; +err: + if (tmr) kfree(tmr); - } - scsiback_do_resp_with_sense(NULL, err, 0, pending_req); - - kmem_cache_free(scsiback_cachep, pending_req); } /* @@ -653,15 +658,53 @@ out: return entry; } -static int prepare_pending_reqs(struct vscsibk_info *info, - struct vscsiif_request *ring_req, - struct vscsibk_pend *pending_req) +static struct vscsibk_pend *scsiback_get_pend_req(struct vscsiif_back_ring *ring, + struct v2p_entry *v2p) +{ + struct scsiback_tpg *tpg = v2p->tpg; + struct scsiback_nexus *nexus = tpg->tpg_nexus; + struct se_session *se_sess = nexus->tvn_se_sess; + struct vscsibk_pend *req; + int tag, i; + + tag = percpu_ida_alloc(&se_sess->sess_tag_pool, TASK_RUNNING); + if (tag < 0) { + pr_err("Unable to obtain tag for vscsiif_request\n"); + return ERR_PTR(-ENOMEM); + } + + req = &((struct vscsibk_pend *)se_sess->sess_cmd_map)[tag]; + memset(req, 0, sizeof(*req)); + req->se_cmd.map_tag = tag; + + for (i = 0; i < VSCSI_MAX_GRANTS; i++) + req->grant_handles[i] = SCSIBACK_INVALID_HANDLE; + + return req; +} + +static struct vscsibk_pend *prepare_pending_reqs(struct vscsibk_info *info, + struct vscsiif_back_ring *ring, + struct vscsiif_request *ring_req) { + struct vscsibk_pend *pending_req; struct v2p_entry *v2p; struct ids_tuple vir; - pending_req->rqid = ring_req->rqid; - pending_req->info = info; + /* request range check from frontend */ + if ((ring_req->sc_data_direction != DMA_BIDIRECTIONAL) && + (ring_req->sc_data_direction != DMA_TO_DEVICE) && + (ring_req->sc_data_direction != DMA_FROM_DEVICE) && + (ring_req->sc_data_direction != DMA_NONE)) { + pr_debug("invalid parameter data_dir = %d\n", + ring_req->sc_data_direction); + return ERR_PTR(-EINVAL); + } + if (ring_req->cmd_len > VSCSIIF_MAX_COMMAND_SIZE) { + pr_debug("invalid parameter cmd_len = %d\n", + ring_req->cmd_len); + return ERR_PTR(-EINVAL); + } vir.chn = ring_req->channel; vir.tgt = ring_req->id; @@ -669,33 +712,24 @@ static int prepare_pending_reqs(struct vscsibk_info *info, v2p = scsiback_do_translation(info, &vir); if (!v2p) { - pending_req->v2p = NULL; pr_debug("the v2p of (chn:%d, tgt:%d, lun:%d) doesn't exist.\n", - vir.chn, vir.tgt, vir.lun); - return -ENODEV; + vir.chn, vir.tgt, vir.lun); + return ERR_PTR(-ENODEV); } - pending_req->v2p = v2p; - /* request range check from frontend */ - pending_req->sc_data_direction = ring_req->sc_data_direction; - if ((pending_req->sc_data_direction != DMA_BIDIRECTIONAL) && - (pending_req->sc_data_direction != DMA_TO_DEVICE) && - (pending_req->sc_data_direction != DMA_FROM_DEVICE) && - (pending_req->sc_data_direction != DMA_NONE)) { - pr_debug("invalid parameter data_dir = %d\n", - pending_req->sc_data_direction); - return -EINVAL; + pending_req = scsiback_get_pend_req(ring, v2p); + if (IS_ERR(pending_req)) { + kref_put(&v2p->kref, scsiback_free_translation_entry); + return ERR_PTR(-ENOMEM); } - + pending_req->rqid = ring_req->rqid; + pending_req->info = info; + pending_req->v2p = v2p; + pending_req->sc_data_direction = ring_req->sc_data_direction; pending_req->cmd_len = ring_req->cmd_len; - if (pending_req->cmd_len > VSCSIIF_MAX_COMMAND_SIZE) { - pr_debug("invalid parameter cmd_len = %d\n", - pending_req->cmd_len); - return -EINVAL; - } memcpy(pending_req->cmnd, ring_req->cmnd, pending_req->cmd_len); - return 0; + return pending_req; } static int scsiback_do_cmd_fn(struct vscsibk_info *info) @@ -704,7 +738,7 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info) struct vscsiif_request ring_req; struct vscsibk_pend *pending_req; RING_IDX rc, rp; - int err, more_to_do; + int more_to_do; uint32_t result; rc = ring->req_cons; @@ -722,16 +756,13 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info) while ((rc != rp)) { if (RING_REQUEST_CONS_OVERFLOW(ring, rc)) break; - pending_req = kmem_cache_alloc(scsiback_cachep, GFP_KERNEL); - if (!pending_req) - return 1; RING_COPY_REQUEST(ring, rc, &ring_req); ring->req_cons = ++rc; - err = prepare_pending_reqs(info, &ring_req, pending_req); - if (err) { - switch (err) { + pending_req = prepare_pending_reqs(info, ring, &ring_req); + if (IS_ERR(pending_req)) { + switch (PTR_ERR(pending_req)) { case -ENODEV: result = DID_NO_CONNECT; break; @@ -739,9 +770,8 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info) result = DRIVER_ERROR; break; } - scsiback_do_resp_with_sense(NULL, result << 24, 0, - pending_req); - kmem_cache_free(scsiback_cachep, pending_req); + scsiback_send_response(info, NULL, result << 24, 0, + ring_req.rqid); return 1; } @@ -750,8 +780,8 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info) if (scsiback_gnttab_data_map(&ring_req, pending_req)) { scsiback_fast_flush_area(pending_req); scsiback_do_resp_with_sense(NULL, - DRIVER_ERROR << 24, 0, pending_req); - kmem_cache_free(scsiback_cachep, pending_req); + DRIVER_ERROR << 24, 0, pending_req); + transport_generic_free_cmd(&pending_req->se_cmd, 0); } else { scsiback_cmd_exec(pending_req); } @@ -765,9 +795,9 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info) break; default: pr_err_ratelimited("invalid request\n"); - scsiback_do_resp_with_sense(NULL, DRIVER_ERROR << 24, - 0, pending_req); - kmem_cache_free(scsiback_cachep, pending_req); + scsiback_do_resp_with_sense(NULL, DRIVER_ERROR << 24, 0, + pending_req); + transport_generic_free_cmd(&pending_req->se_cmd, 0); break; } @@ -1353,24 +1383,20 @@ static u32 scsiback_tpg_get_inst_index(struct se_portal_group *se_tpg) static int scsiback_check_stop_free(struct se_cmd *se_cmd) { - /* - * Do not release struct se_cmd's containing a valid TMR pointer. - * These will be released directly in scsiback_device_action() - * with transport_generic_free_cmd(). - */ - if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) - return 0; - - transport_generic_free_cmd(se_cmd, 0); - return 1; + return transport_generic_free_cmd(se_cmd, 0); } static void scsiback_release_cmd(struct se_cmd *se_cmd) { - struct vscsibk_pend *pending_req = container_of(se_cmd, - struct vscsibk_pend, se_cmd); + struct se_session *se_sess = se_cmd->se_sess; + struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; + + if (se_tmr && se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) { + struct scsiback_tmr *tmr = se_tmr->fabric_tmr_ptr; + kfree(tmr); + } - kmem_cache_free(scsiback_cachep, pending_req); + percpu_ida_free(&se_sess->sess_tag_pool, se_cmd->map_tag); } static int scsiback_shutdown_session(struct se_session *se_sess) @@ -1494,61 +1520,49 @@ static struct configfs_attribute *scsiback_param_attrs[] = { NULL, }; +static int scsiback_alloc_sess_cb(struct se_portal_group *se_tpg, + struct se_session *se_sess, void *p) +{ + struct scsiback_tpg *tpg = container_of(se_tpg, + struct scsiback_tpg, se_tpg); + + tpg->tpg_nexus = p; + return 0; +} + static int scsiback_make_nexus(struct scsiback_tpg *tpg, const char *name) { - struct se_portal_group *se_tpg; - struct se_session *se_sess; struct scsiback_nexus *tv_nexus; + int ret = 0; mutex_lock(&tpg->tv_tpg_mutex); if (tpg->tpg_nexus) { - mutex_unlock(&tpg->tv_tpg_mutex); pr_debug("tpg->tpg_nexus already exists\n"); - return -EEXIST; + ret = -EEXIST; + goto out_unlock; } - se_tpg = &tpg->se_tpg; tv_nexus = kzalloc(sizeof(struct scsiback_nexus), GFP_KERNEL); if (!tv_nexus) { - mutex_unlock(&tpg->tv_tpg_mutex); - return -ENOMEM; + ret = -ENOMEM; + goto out_unlock; } - /* - * Initialize the struct se_session pointer - */ - tv_nexus->tvn_se_sess = transport_init_session(TARGET_PROT_NORMAL); + + tv_nexus->tvn_se_sess = target_alloc_session(&tpg->se_tpg, + VSCSI_DEFAULT_SESSION_TAGS, + sizeof(struct vscsibk_pend), + TARGET_PROT_NORMAL, name, + tv_nexus, scsiback_alloc_sess_cb); if (IS_ERR(tv_nexus->tvn_se_sess)) { - mutex_unlock(&tpg->tv_tpg_mutex); kfree(tv_nexus); - return -ENOMEM; + ret = -ENOMEM; + goto out_unlock; } - se_sess = tv_nexus->tvn_se_sess; - /* - * Since we are running in 'demo mode' this call with generate a - * struct se_node_acl for the scsiback struct se_portal_group with - * the SCSI Initiator port name of the passed configfs group 'name'. - */ - tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl( - se_tpg, (unsigned char *)name); - if (!tv_nexus->tvn_se_sess->se_node_acl) { - mutex_unlock(&tpg->tv_tpg_mutex); - pr_debug("core_tpg_check_initiator_node_acl() failed for %s\n", - name); - goto out; - } - /* Now register the TCM pvscsi virtual I_T Nexus as active. */ - transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl, - tv_nexus->tvn_se_sess, tv_nexus); - tpg->tpg_nexus = tv_nexus; +out_unlock: mutex_unlock(&tpg->tv_tpg_mutex); - return 0; - -out: - transport_free_session(se_sess); - kfree(tv_nexus); - return -ENOMEM; + return ret; } static int scsiback_drop_nexus(struct scsiback_tpg *tpg) @@ -1866,16 +1880,6 @@ static struct xenbus_driver scsiback_driver = { .otherend_changed = scsiback_frontend_changed }; -static void scsiback_init_pend(void *p) -{ - struct vscsibk_pend *pend = p; - int i; - - memset(pend, 0, sizeof(*pend)); - for (i = 0; i < VSCSI_MAX_GRANTS; i++) - pend->grant_handles[i] = SCSIBACK_INVALID_HANDLE; -} - static int __init scsiback_init(void) { int ret; @@ -1886,14 +1890,9 @@ static int __init scsiback_init(void) pr_debug("xen-pvscsi: fabric module %s on %s/%s on "UTS_RELEASE"\n", VSCSI_VERSION, utsname()->sysname, utsname()->machine); - scsiback_cachep = kmem_cache_create("vscsiif_cache", - sizeof(struct vscsibk_pend), 0, 0, scsiback_init_pend); - if (!scsiback_cachep) - return -ENOMEM; - ret = xenbus_register_backend(&scsiback_driver); if (ret) - goto out_cache_destroy; + goto out; ret = target_register_template(&scsiback_ops); if (ret) @@ -1903,8 +1902,7 @@ static int __init scsiback_init(void) out_unregister_xenbus: xenbus_unregister_driver(&scsiback_driver); -out_cache_destroy: - kmem_cache_destroy(scsiback_cachep); +out: pr_err("%s: error %d\n", __func__, ret); return ret; } @@ -1920,7 +1918,6 @@ static void __exit scsiback_exit(void) } target_unregister_template(&scsiback_ops); xenbus_unregister_driver(&scsiback_driver); - kmem_cache_destroy(scsiback_cachep); } module_init(scsiback_init); diff --git a/drivers/xen/xen-selfballoon.c b/drivers/xen/xen-selfballoon.c index 3b2bffde5..53a085fca 100644 --- a/drivers/xen/xen-selfballoon.c +++ b/drivers/xen/xen-selfballoon.c @@ -71,7 +71,6 @@ #include <linux/swap.h> #include <linux/mm.h> #include <linux/mman.h> -#include <linux/module.h> #include <linux/workqueue.h> #include <linux/device.h> #include <xen/balloon.h> diff --git a/drivers/xen/xenbus/xenbus_dev_backend.c b/drivers/xen/xenbus/xenbus_dev_backend.c index ee6d9efd7..4a41ac9af 100644 --- a/drivers/xen/xenbus/xenbus_dev_backend.c +++ b/drivers/xen/xenbus/xenbus_dev_backend.c @@ -5,7 +5,7 @@ #include <linux/mm.h> #include <linux/fs.h> #include <linux/miscdevice.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/capability.h> #include <xen/xen.h> @@ -18,8 +18,6 @@ #include "xenbus_comms.h" -MODULE_LICENSE("GPL"); - static int xenbus_backend_open(struct inode *inode, struct file *filp) { if (!capable(CAP_SYS_ADMIN)) @@ -132,11 +130,4 @@ static int __init xenbus_backend_init(void) pr_err("Could not register xenbus backend device\n"); return err; } - -static void __exit xenbus_backend_exit(void) -{ - misc_deregister(&xenbus_backend_dev); -} - -module_init(xenbus_backend_init); -module_exit(xenbus_backend_exit); +device_initcall(xenbus_backend_init); diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c index 912b64edb..cacf30d14 100644 --- a/drivers/xen/xenbus/xenbus_dev_frontend.c +++ b/drivers/xen/xenbus/xenbus_dev_frontend.c @@ -55,7 +55,7 @@ #include <linux/string.h> #include <linux/slab.h> #include <linux/miscdevice.h> -#include <linux/module.h> +#include <linux/init.h> #include "xenbus_comms.h" @@ -63,8 +63,6 @@ #include <xen/xen.h> #include <asm/xen/hypervisor.h> -MODULE_LICENSE("GPL"); - /* * An element of a list of outstanding transactions, for which we're * still waiting a reply. @@ -626,11 +624,4 @@ static int __init xenbus_init(void) pr_err("Could not register xenbus frontend device\n"); return err; } - -static void __exit xenbus_exit(void) -{ - misc_deregister(&xenbus_dev); -} - -module_init(xenbus_init); -module_exit(xenbus_exit); +device_initcall(xenbus_init); diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index ba804f3d8..374b12af8 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c @@ -44,7 +44,6 @@ #include <linux/fcntl.h> #include <linux/kthread.h> #include <linux/rwsem.h> -#include <linux/module.h> #include <linux/mutex.h> #include <asm/xen/hypervisor.h> #include <xen/xenbus.h> diff --git a/drivers/xen/xenfs/xensyms.c b/drivers/xen/xenfs/xensyms.c index a03f261b1..c6e2b4a54 100644 --- a/drivers/xen/xenfs/xensyms.c +++ b/drivers/xen/xenfs/xensyms.c @@ -1,4 +1,3 @@ -#include <linux/module.h> #include <linux/init.h> #include <linux/seq_file.h> #include <linux/fs.h> |