cregit-Linux how code gets into the kernel

Release 4.11 drivers/hv/vmbus_drv.c

Directory: drivers/hv
/*
 * Copyright (c) 2009, Microsoft Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place - Suite 330, Boston, MA 02111-1307 USA.
 *
 * Authors:
 *   Haiyang Zhang <haiyangz@microsoft.com>
 *   Hank Janssen  <hjanssen@microsoft.com>
 *   K. Y. Srinivasan <kys@microsoft.com>
 *
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/sysctl.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/completion.h>
#include <linux/hyperv.h>
#include <linux/kernel_stat.h>
#include <linux/clockchips.h>
#include <linux/cpu.h>
#include <linux/sched/task_stack.h>

#include <asm/hyperv.h>
#include <asm/hypervisor.h>
#include <asm/mshyperv.h>
#include <linux/notifier.h>
#include <linux/ptrace.h>
#include <linux/screen_info.h>
#include <linux/kdebug.h>
#include <linux/efi.h>
#include <linux/random.h>
#include "hyperv_vmbus.h"


struct vmbus_dynid {
	
struct list_head node;
	
struct hv_vmbus_device_id id;
};


static struct acpi_device  *hv_acpi_dev;


static struct completion probe_event;


static int hyperv_cpuhp_online;


static int hyperv_panic_event(struct notifier_block *nb, unsigned long val, void *args) { struct pt_regs *regs; regs = current_pt_regs(); hyperv_report_panic(regs); return NOTIFY_DONE; }

Contributors

PersonTokensPropCommitsCommitProp
Vitaly Kuznetsov37100.00%1100.00%
Total37100.00%1100.00%


static int hyperv_die_event(struct notifier_block *nb, unsigned long val, void *args) { struct die_args *die = (struct die_args *)args; struct pt_regs *regs = die->regs; hyperv_report_panic(regs); return NOTIFY_DONE; }

Contributors

PersonTokensPropCommitsCommitProp
Vitaly Kuznetsov4491.67%150.00%
Nick Meier48.33%150.00%
Total48100.00%2100.00%

static struct notifier_block hyperv_die_block = { .notifier_call = hyperv_die_event, }; static struct notifier_block hyperv_panic_block = { .notifier_call = hyperv_panic_event, }; static const char *fb_mmio_name = "fb_range"; static struct resource *fb_mmio; static struct resource *hyperv_mmio; static DEFINE_SEMAPHORE(hyperv_mmio_lock);
static int vmbus_exists(void) { if (hv_acpi_dev == NULL) return -ENODEV; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
K. Y. Srinivasan21100.00%1100.00%
Total21100.00%1100.00%

#define VMBUS_ALIAS_LEN ((sizeof((struct hv_vmbus_device_id *)0)->guid) * 2)
static void print_alias_name(struct hv_device *hv_dev, char *alias_name) { int i; for (i = 0; i < VMBUS_ALIAS_LEN; i += 2) sprintf(&alias_name[i], "%02x", hv_dev->dev_type.b[i/2]); }

Contributors

PersonTokensPropCommitsCommitProp
Olaf Hering54100.00%1100.00%
Total54100.00%1100.00%


static u8 channel_monitor_group(struct vmbus_channel *channel) { return (u8)channel->offermsg.monitorid / 32; }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman23100.00%1100.00%
Total23100.00%1100.00%


static u8 channel_monitor_offset(struct vmbus_channel *channel) { return (u8)channel->offermsg.monitorid % 32; }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman23100.00%1100.00%
Total23100.00%1100.00%


static u32 channel_pending(struct vmbus_channel *channel, struct hv_monitor_page *monitor_page) { u8 monitor_group = channel_monitor_group(channel); return monitor_page->trigger_group[monitor_group].pending; }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman34100.00%1100.00%
Total34100.00%1100.00%


static u32 channel_latency(struct vmbus_channel *channel, struct hv_monitor_page *monitor_page) { u8 monitor_group = channel_monitor_group(channel); u8 monitor_offset = channel_monitor_offset(channel); return monitor_page->latency[monitor_group][monitor_offset]; }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman43100.00%1100.00%
Total43100.00%1100.00%


static u32 channel_conn_id(struct vmbus_channel *channel, struct hv_monitor_page *monitor_page) { u8 monitor_group = channel_monitor_group(channel); u8 monitor_offset = channel_monitor_offset(channel); return monitor_page->parameter[monitor_group][monitor_offset].connectionid.u.id; }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman49100.00%1100.00%
Total49100.00%1100.00%


static ssize_t id_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); if (!hv_dev->channel) return -ENODEV; return sprintf(buf, "%d\n", hv_dev->channel->offermsg.child_relid); }

Contributors

PersonTokensPropCommitsCommitProp
K. Y. Srinivasan3154.39%457.14%
Greg Kroah-Hartman1322.81%114.29%
Timo Teräs1017.54%114.29%
Hank Janssen35.26%114.29%
Total57100.00%7100.00%

static DEVICE_ATTR_RO(id);
static ssize_t state_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); if (!hv_dev->channel) return -ENODEV; return sprintf(buf, "%d\n", hv_dev->channel->state); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman3767.27%120.00%
K. Y. Srinivasan1832.73%480.00%
Total55100.00%5100.00%

static DEVICE_ATTR_RO(state);
static ssize_t monitor_id_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); if (!hv_dev->channel) return -ENODEV; return sprintf(buf, "%d\n", hv_dev->channel->offermsg.monitorid); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman3968.42%125.00%
K. Y. Srinivasan1831.58%375.00%
Total57100.00%4100.00%

static DEVICE_ATTR_RO(monitor_id);
static ssize_t class_id_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); if (!hv_dev->channel) return -ENODEV; return sprintf(buf, "{%pUl}\n", hv_dev->channel->offermsg.offer.if_type.b); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman4472.13%125.00%
K. Y. Srinivasan1727.87%375.00%
Total61100.00%4100.00%

static DEVICE_ATTR_RO(class_id);
static ssize_t device_id_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); if (!hv_dev->channel) return -ENODEV; return sprintf(buf, "{%pUl}\n", hv_dev->channel->offermsg.offer.if_instance.b); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman4472.13%125.00%
K. Y. Srinivasan1727.87%375.00%
Total61100.00%4100.00%

static DEVICE_ATTR_RO(device_id);
static ssize_t modalias_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); char alias_name[VMBUS_ALIAS_LEN + 1]; print_alias_name(hv_dev, alias_name); return sprintf(buf, "vmbus:%s\n", alias_name); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman55100.00%2100.00%
Total55100.00%2100.00%

static DEVICE_ATTR_RO(modalias);
static ssize_t server_monitor_pending_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); if (!hv_dev->channel) return -ENODEV; return sprintf(buf, "%d\n", channel_pending(hv_dev->channel, vmbus_connection.monitor_pages[1])); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman63100.00%2100.00%
Total63100.00%2100.00%

static DEVICE_ATTR_RO(server_monitor_pending);
static ssize_t client_monitor_pending_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); if (!hv_dev->channel) return -ENODEV; return sprintf(buf, "%d\n", channel_pending(hv_dev->channel, vmbus_connection.monitor_pages[1])); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman63100.00%2100.00%
Total63100.00%2100.00%

static DEVICE_ATTR_RO(client_monitor_pending);
static ssize_t server_monitor_latency_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); if (!hv_dev->channel) return -ENODEV; return sprintf(buf, "%d\n", channel_latency(hv_dev->channel, vmbus_connection.monitor_pages[0])); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman63100.00%2100.00%
Total63100.00%2100.00%

static DEVICE_ATTR_RO(server_monitor_latency);
static ssize_t client_monitor_latency_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); if (!hv_dev->channel) return -ENODEV; return sprintf(buf, "%d\n", channel_latency(hv_dev->channel, vmbus_connection.monitor_pages[1])); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman63100.00%2100.00%
Total63100.00%2100.00%

static DEVICE_ATTR_RO(client_monitor_latency);
static ssize_t server_monitor_conn_id_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); if (!hv_dev->channel) return -ENODEV; return sprintf(buf, "%d\n", channel_conn_id(hv_dev->channel, vmbus_connection.monitor_pages[0])); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman63100.00%2100.00%
Total63100.00%2100.00%

static DEVICE_ATTR_RO(server_monitor_conn_id);
static ssize_t client_monitor_conn_id_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); if (!hv_dev->channel) return -ENODEV; return sprintf(buf, "%d\n", channel_conn_id(hv_dev->channel, vmbus_connection.monitor_pages[1])); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman63100.00%2100.00%
Total63100.00%2100.00%

static DEVICE_ATTR_RO(client_monitor_conn_id);
static ssize_t out_intr_mask_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); struct hv_ring_buffer_debug_info outbound; if (!hv_dev->channel) return -ENODEV; hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound); return sprintf(buf, "%d\n", outbound.current_interrupt_mask); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman70100.00%2100.00%
Total70100.00%2100.00%

static DEVICE_ATTR_RO(out_intr_mask);
static ssize_t out_read_index_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); struct hv_ring_buffer_debug_info outbound; if (!hv_dev->channel) return -ENODEV; hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound); return sprintf(buf, "%d\n", outbound.current_read_index); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman70100.00%2100.00%
Total70100.00%2100.00%

static DEVICE_ATTR_RO(out_read_index);
static ssize_t out_write_index_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); struct hv_ring_buffer_debug_info outbound; if (!hv_dev->channel) return -ENODEV; hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound); return sprintf(buf, "%d\n", outbound.current_write_index); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman70100.00%2100.00%
Total70100.00%2100.00%

static DEVICE_ATTR_RO(out_write_index);
static ssize_t out_read_bytes_avail_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); struct hv_ring_buffer_debug_info outbound; if (!hv_dev->channel) return -ENODEV; hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound); return sprintf(buf, "%d\n", outbound.bytes_avail_toread); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman70100.00%2100.00%
Total70100.00%2100.00%

static DEVICE_ATTR_RO(out_read_bytes_avail);
static ssize_t out_write_bytes_avail_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); struct hv_ring_buffer_debug_info outbound; if (!hv_dev->channel) return -ENODEV; hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound); return sprintf(buf, "%d\n", outbound.bytes_avail_towrite); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman70100.00%2100.00%
Total70100.00%2100.00%

static DEVICE_ATTR_RO(out_write_bytes_avail);
static ssize_t in_intr_mask_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); struct hv_ring_buffer_debug_info inbound; if (!hv_dev->channel) return -ENODEV; hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound); return sprintf(buf, "%d\n", inbound.current_interrupt_mask); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman70100.00%2100.00%
Total70100.00%2100.00%

static DEVICE_ATTR_RO(in_intr_mask);
static ssize_t in_read_index_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); struct hv_ring_buffer_debug_info inbound; if (!hv_dev->channel) return -ENODEV; hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound); return sprintf(buf, "%d\n", inbound.current_read_index); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman70100.00%2100.00%
Total70100.00%2100.00%

static DEVICE_ATTR_RO(in_read_index);
static ssize_t in_write_index_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); struct hv_ring_buffer_debug_info inbound; if (!hv_dev->channel) return -ENODEV; hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound); return sprintf(buf, "%d\n", inbound.current_write_index); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman70100.00%2100.00%
Total70100.00%2100.00%

static DEVICE_ATTR_RO(in_write_index);
static ssize_t in_read_bytes_avail_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); struct hv_ring_buffer_debug_info inbound; if (!hv_dev->channel) return -ENODEV; hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound); return sprintf(buf, "%d\n", inbound.bytes_avail_toread); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman70100.00%2100.00%
Total70100.00%2100.00%

static DEVICE_ATTR_RO(in_read_bytes_avail);
static ssize_t in_write_bytes_avail_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); struct hv_ring_buffer_debug_info inbound; if (!hv_dev->channel) return -ENODEV; hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound); return sprintf(buf, "%d\n", inbound.bytes_avail_towrite); }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman70100.00%2100.00%
Total70100.00%2100.00%

static DEVICE_ATTR_RO(in_write_bytes_avail);
static ssize_t channel_vp_mapping_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); struct vmbus_channel *channel = hv_dev->channel, *cur_sc; unsigned long flags; int buf_size = PAGE_SIZE, n_written, tot_written; struct list_head *cur; if (!channel) return -ENODEV; tot_written = snprintf(buf, buf_size, "%u:%u\n", channel->offermsg.child_relid, channel->target_cpu); spin_lock_irqsave(&channel->lock, flags); list_for_each(cur, &channel->sc_list) { if (tot_written >= buf_size - 1) break; cur_sc = list_entry(cur, struct vmbus_channel, sc_list); n_written = scnprintf(buf + tot_written, buf_size - tot_written, "%u:%u\n", cur_sc->offermsg.child_relid, cur_sc->target_cpu); tot_written += n_written; } spin_unlock_irqrestore(&channel->lock, flags); return tot_written; }

Contributors

PersonTokensPropCommitsCommitProp
Dexuan Cui171100.00%1100.00%
Total171100.00%1100.00%

static DEVICE_ATTR_RO(channel_vp_mapping);
static ssize_t vendor_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); return sprintf(buf, "0x%x\n", hv_dev->vendor_id); }

Contributors

PersonTokensPropCommitsCommitProp
K. Y. Srinivasan42100.00%1100.00%
Total42100.00%1100.00%

static DEVICE_ATTR_RO(vendor);
static ssize_t device_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct hv_device *hv_dev = device_to_hv_device(dev); return sprintf(buf, "0x%x\n", hv_dev->device_id); }

Contributors

PersonTokensPropCommitsCommitProp
K. Y. Srinivasan42100.00%1100.00%
Total42100.00%1100.00%

static DEVICE_ATTR_RO(device); /* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */ static struct attribute *vmbus_dev_attrs[] = { &dev_attr_id.attr, &dev_attr_state.attr, &dev_attr_monitor_id.attr, &dev_attr_class_id.attr, &dev_attr_device_id.attr, &dev_attr_modalias.attr, &dev_attr_server_monitor_pending.attr, &dev_attr_client_monitor_pending.attr, &dev_attr_server_monitor_latency.attr, &dev_attr_client_monitor_latency.attr, &dev_attr_server_monitor_conn_id.attr, &dev_attr_client_monitor_conn_id.attr, &dev_attr_out_intr_mask.attr, &dev_attr_out_read_index.attr, &dev_attr_out_write_index.attr, &dev_attr_out_read_bytes_avail.attr, &dev_attr_out_write_bytes_avail.attr, &dev_attr_in_intr_mask.attr, &dev_attr_in_read_index.attr, &dev_attr_in_write_index.attr, &dev_attr_in_read_bytes_avail.attr, &dev_attr_in_write_bytes_avail.attr, &dev_attr_channel_vp_mapping.attr, &dev_attr_vendor.attr, &dev_attr_device.attr, NULL, }; ATTRIBUTE_GROUPS(vmbus_dev); /* * vmbus_uevent - add uevent for our device * * This routine is invoked when a device is added or removed on the vmbus to * generate a uevent to udev in the userspace. The udev will then look at its * rule and the uevent generated here to load the appropriate driver * * The alias string will be of the form vmbus:guid where guid is the string * representation of the device guid (each byte of the guid will be * represented with two hex characters. */
static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) { struct hv_device *dev = device_to_hv_device(device); int ret; char alias_name[VMBUS_ALIAS_LEN + 1]; print_alias_name(dev, alias_name); ret = add_uevent_var(env, "MODALIAS=vmbus:%s", alias_name); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
K. Y. Srinivasan4679.31%350.00%
Olaf Hering712.07%116.67%
Hank Janssen46.90%116.67%
Greg Kroah-Hartman11.72%116.67%
Total58100.00%6100.00%

static const uuid_le null_guid;
static inline bool is_null_guid(const uuid_le *guid) { if (uuid_le_cmp(*guid, null_guid)) return false; return true; }

Contributors

PersonTokensPropCommitsCommitProp
K. Y. Srinivasan28100.00%3100.00%
Total28100.00%3100.00%

/* * Return a matching hv_vmbus_device_id pointer. * If there is no match, return NULL. */
static const struct hv_vmbus_device_id *hv_vmbus_get_id(struct hv_driver *drv, const uuid_le *guid) { const struct hv_vmbus_device_id *id = NULL; struct vmbus_dynid *dynid; /* Look at the dynamic ids first, before the static ones */ spin_lock(&drv->dynids.lock); list_for_each_entry(dynid, &drv->dynids.list, node) { if (!uuid_le_cmp(dynid->id.guid, *guid)) { id = &dynid->id; break; } } spin_unlock(&drv->dynids.lock); if (id) return id; id = drv->id_table; if (id == NULL) return NULL; /* empty device table */ for (; !is_null_guid(&id->guid); id++) if (!uuid_le_cmp(id->guid, *guid)) return id; return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Stephen Hemminger9565.52%240.00%
K. Y. Srinivasan5034.48%360.00%
Total145100.00%5100.00%

/* vmbus_add_dynid - add a new device ID to this driver and re-probe devices */
static int vmbus_add_dynid(struct hv_driver *drv, uuid_le *guid) { struct vmbus_dynid *dynid; dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); if (!dynid) return -ENOMEM; dynid->id.guid = *guid; spin_lock(&drv->dynids.lock); list_add_tail(&dynid->node, &drv->dynids.list); spin_unlock(&drv->dynids.lock); return driver_attach(&drv->driver); }

Contributors

PersonTokensPropCommitsCommitProp
Stephen Hemminger6669.47%114.29%
K. Y. Srinivasan2425.26%571.43%
Dexuan Cui55.26%114.29%
Total95100.00%7100.00%


static void vmbus_free_dynids(struct hv_driver *drv) { struct vmbus_dynid *dynid, *n; spin_lock(&drv->dynids.lock); list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { list_del(&dynid->node)