drivers/xen/pvcalls-back.c
Source file repositories/reference/linux-study-clean/drivers/xen/pvcalls-back.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/xen/pvcalls-back.c- Extension
.c- Size
- 30633 bytes
- Lines
- 1252
- Domain
- Driver Families
- Bucket
- drivers/xen
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/inet.hlinux/kthread.hlinux/list.hlinux/radix-tree.hlinux/module.hlinux/semaphore.hlinux/wait.hnet/sock.hnet/inet_common.hnet/inet_connection_sock.hnet/request_sock.htrace/events/sock.hxen/events.hxen/grant_table.hxen/xen.hxen/xenbus.hxen/interface/io/pvcalls.h
Detected Declarations
struct pvcalls_fedatastruct pvcalls_ioworkerstruct sock_mappingstruct sockpass_mappingfunction pvcalls_conn_back_readfunction pvcalls_conn_back_writefunction pvcalls_back_ioworkerfunction pvcalls_back_socketfunction pvcalls_sk_state_changefunction pvcalls_sk_data_readyfunction pvcalls_back_connectfunction pvcalls_back_release_activefunction pvcalls_back_release_passivefunction pvcalls_back_releasefunction __pvcalls_back_acceptfunction pvcalls_pass_sk_data_readyfunction pvcalls_back_bindfunction pvcalls_back_listenfunction pvcalls_back_acceptfunction pvcalls_back_pollfunction pvcalls_back_handle_cmdfunction pvcalls_back_workfunction pvcalls_back_eventfunction pvcalls_back_conn_eventfunction backend_connectfunction backend_disconnectfunction radix_tree_for_each_slotfunction pvcalls_back_probefunction set_backend_statefunction pvcalls_back_changedfunction pvcalls_back_removefunction pvcalls_back_initfunction pvcalls_back_finmodule init pvcalls_back_init
Annotated Snippet
ret = sock_create(AF_INET, SOCK_STREAM, 0, &sock);
if (ret < 0)
goto out;
ret = inet_stream_connect(sock, (struct sockaddr_unsized *)sa, req->u.connect.len, 0);
if (ret < 0) {
sock_release(sock);
goto out;
}
map = pvcalls_new_active_socket(fedata,
req->u.connect.id,
req->u.connect.ref,
req->u.connect.evtchn,
sock);
if (!map)
ret = -EFAULT;
out:
rsp = RING_GET_RESPONSE(&fedata->ring, fedata->ring.rsp_prod_pvt++);
rsp->req_id = req->req_id;
rsp->cmd = req->cmd;
rsp->u.connect.id = req->u.connect.id;
rsp->ret = ret;
return 0;
}
static int pvcalls_back_release_active(struct xenbus_device *dev,
struct pvcalls_fedata *fedata,
struct sock_mapping *map)
{
disable_irq(map->irq);
if (map->sock->sk != NULL) {
write_lock_bh(&map->sock->sk->sk_callback_lock);
map->sock->sk->sk_user_data = NULL;
map->sock->sk->sk_data_ready = map->saved_data_ready;
write_unlock_bh(&map->sock->sk->sk_callback_lock);
}
atomic_set(&map->release, 1);
flush_work(&map->ioworker.register_work);
xenbus_unmap_ring_vfree(dev, map->bytes);
xenbus_unmap_ring_vfree(dev, (void *)map->ring);
unbind_from_irqhandler(map->irq, map);
sock_release(map->sock);
kfree(map);
return 0;
}
static int pvcalls_back_release_passive(struct xenbus_device *dev,
struct pvcalls_fedata *fedata,
struct sockpass_mapping *mappass)
{
if (mappass->sock->sk != NULL) {
write_lock_bh(&mappass->sock->sk->sk_callback_lock);
mappass->sock->sk->sk_user_data = NULL;
mappass->sock->sk->sk_data_ready = mappass->saved_data_ready;
write_unlock_bh(&mappass->sock->sk->sk_callback_lock);
}
sock_release(mappass->sock);
destroy_workqueue(mappass->wq);
kfree(mappass);
return 0;
}
static int pvcalls_back_release(struct xenbus_device *dev,
struct xen_pvcalls_request *req)
{
struct pvcalls_fedata *fedata;
struct sock_mapping *map, *n;
struct sockpass_mapping *mappass;
int ret = 0;
struct xen_pvcalls_response *rsp;
fedata = dev_get_drvdata(&dev->dev);
down(&fedata->socket_lock);
list_for_each_entry_safe(map, n, &fedata->socket_mappings, list) {
if (map->id == req->u.release.id) {
list_del(&map->list);
up(&fedata->socket_lock);
ret = pvcalls_back_release_active(dev, fedata, map);
goto out;
}
}
mappass = radix_tree_lookup(&fedata->socketpass_mappings,
Annotation
- Immediate include surface: `linux/inet.h`, `linux/kthread.h`, `linux/list.h`, `linux/radix-tree.h`, `linux/module.h`, `linux/semaphore.h`, `linux/wait.h`, `net/sock.h`.
- Detected declarations: `struct pvcalls_fedata`, `struct pvcalls_ioworker`, `struct sock_mapping`, `struct sockpass_mapping`, `function pvcalls_conn_back_read`, `function pvcalls_conn_back_write`, `function pvcalls_back_ioworker`, `function pvcalls_back_socket`, `function pvcalls_sk_state_change`, `function pvcalls_sk_data_ready`.
- Atlas domain: Driver Families / drivers/xen.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.