Skip to content

Commit e8b767f

Browse files
committed
Merge tag 'for-linus-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml
Pull UML updates from Richard Weinberger: - Devicetree support (for testing) - Various cleanups and fixes: UBD, port_user, uml_mconsole - Maintainer update * tag 'for-linus-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml: um: run_helper: Write error message to kernel log on exec failure on host um: port_user: Improve error handling when port-helper is not found um: port_user: Allow setting path to port-helper using UML_PORT_HELPER envvar um: port_user: Search for in.telnetd in PATH um: clang: Strip out -mno-global-merge from USER_CFLAGS docs: UML: Mention telnetd for port channel um: Remove unused timeval_to_ns() function um: Fix uml_mconsole stop/go um: Cleanup syscall_handler_t definition/cast, fix warning uml: net: vector: fix const issue um: Fix WRITE_ZEROES in the UBD Driver um: Migrate vector drivers to NAPI um: Fix order of dtb unflatten/early init um: fix and optimize xor select template for CONFIG64 and timetravel mode um: Document dtb command line option lib/logic_iomem: correct fallback config references um: Remove duplicated include in syscalls_64.c MAINTAINERS: Update UserModeLinux entry
2 parents a87a08e + 8201745 commit e8b767f

File tree

19 files changed

+131
-80
lines changed

19 files changed

+131
-80
lines changed

Documentation/virt/uml/user_mode_linux_howto_v2.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,26 @@ E.g. ``os_close_file()`` is just a wrapper around ``close()``
11931193
which ensures that the userspace function close does not clash
11941194
with similarly named function(s) in the kernel part.
11951195

1196+
Using UML as a Test Platform
1197+
============================
1198+
1199+
UML is an excellent test platform for device driver development. As
1200+
with most things UML, "some user assembly may be required". It is
1201+
up to the user to build their emulation environment. UML at present
1202+
provides only the kernel infrastructure.
1203+
1204+
Part of this infrastructure is the ability to load and parse fdt
1205+
device tree blobs as used in Arm or Open Firmware platforms. These
1206+
are supplied as an optional extra argument to the kernel command
1207+
line::
1208+
1209+
dtb=filename
1210+
1211+
The device tree is loaded and parsed at boottime and is accessible by
1212+
drivers which query it. At this moment in time this facility is
1213+
intended solely for development purposes. UML's own devices do not
1214+
query the device tree.
1215+
11961216
Security Considerations
11971217
-----------------------
11981218

MAINTAINERS

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20539,14 +20539,15 @@ F: Documentation/admin-guide/media/zr364xx*
2053920539
F: drivers/media/usb/zr364xx/
2054020540

2054120541
USER-MODE LINUX (UML)
20542-
M: Jeff Dike <jdike@addtoit.com>
2054320542
M: Richard Weinberger <richard@nod.at>
2054420543
M: Anton Ivanov <anton.ivanov@cambridgegreys.com>
20544+
M: Johannes Berg <johannes@sipsolutions.net>
2054520545
L: linux-um@lists.infradead.org
2054620546
S: Maintained
2054720547
W: http://user-mode-linux.sourceforge.net
2054820548
Q: https://patchwork.ozlabs.org/project/linux-um/list/
20549-
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml.git
20549+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux.git next
20550+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux.git fixes
2055020551
F: Documentation/virt/uml/
2055120552
F: arch/um/
2055220553
F: arch/x86/um/

arch/um/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \
7575
-D_FILE_OFFSET_BITS=64 -idirafter $(srctree)/include \
7676
-idirafter $(objtree)/include -D__KERNEL__ -D__UM_HOST__
7777

78+
ifdef CONFIG_CC_IS_CLANG
79+
USER_CFLAGS := $(patsubst -mno-global-merge,,$(USER_CFLAGS))
80+
endif
81+
7882
#This will adjust *FLAGS accordingly to the platform.
7983
include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
8084

arch/um/drivers/mconsole_kern.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ void mconsole_go(struct mc_request *req)
224224

225225
void mconsole_stop(struct mc_request *req)
226226
{
227-
deactivate_fd(req->originating_fd, MCONSOLE_IRQ);
227+
block_signals();
228228
os_set_fd_block(req->originating_fd, 1);
229229
mconsole_reply(req, "stopped", 0, 0);
230230
for (;;) {
@@ -247,6 +247,7 @@ void mconsole_stop(struct mc_request *req)
247247
}
248248
os_set_fd_block(req->originating_fd, 0);
249249
mconsole_reply(req, "", 0, 0);
250+
unblock_signals();
250251
}
251252

252253
static DEFINE_SPINLOCK(mc_devices_lock);

arch/um/drivers/port_user.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <stdio.h>
77
#include <stdlib.h>
8+
#include <string.h>
89
#include <errno.h>
910
#include <termios.h>
1011
#include <unistd.h>
@@ -167,14 +168,29 @@ static void port_pre_exec(void *arg)
167168
int port_connection(int fd, int *socket, int *pid_out)
168169
{
169170
int new, err;
170-
char *argv[] = { "/usr/sbin/in.telnetd", "-L",
171+
char *env;
172+
char *argv[] = { "in.telnetd", "-L",
171173
OS_LIB_PATH "/uml/port-helper", NULL };
172174
struct port_pre_exec_data data;
173175

176+
if ((env = getenv("UML_PORT_HELPER")))
177+
argv[2] = env;
178+
174179
new = accept(fd, NULL, 0);
175180
if (new < 0)
176181
return -errno;
177182

183+
err = os_access(argv[2], X_OK);
184+
if (err < 0) {
185+
printk(UM_KERN_ERR "port_connection : error accessing port-helper "
186+
"executable at %s: %s\n", argv[2], strerror(-err));
187+
if (env == NULL)
188+
printk(UM_KERN_ERR "Set UML_PORT_HELPER environment "
189+
"variable to path to uml-utilities port-helper "
190+
"binary\n");
191+
goto out_close;
192+
}
193+
178194
err = os_pipe(socket, 0, 0);
179195
if (err < 0)
180196
goto out_close;

arch/um/drivers/ubd_kern.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1526,13 +1526,19 @@ static void do_io(struct io_thread_req *req, struct io_desc *desc)
15261526
}
15271527
break;
15281528
case REQ_OP_DISCARD:
1529-
case REQ_OP_WRITE_ZEROES:
15301529
n = os_falloc_punch(req->fds[bit], off, len);
15311530
if (n) {
15321531
req->error = map_error(-n);
15331532
return;
15341533
}
15351534
break;
1535+
case REQ_OP_WRITE_ZEROES:
1536+
n = os_falloc_zeroes(req->fds[bit], off, len);
1537+
if (n) {
1538+
req->error = map_error(-n);
1539+
return;
1540+
}
1541+
break;
15361542
default:
15371543
WARN_ON_ONCE(1);
15381544
req->error = BLK_STS_NOTSUPP;

arch/um/drivers/vector_kern.c

Lines changed: 49 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ static LIST_HEAD(vector_devices);
6767
static int driver_registered;
6868

6969
static void vector_eth_configure(int n, struct arglist *def);
70+
static int vector_mmsg_rx(struct vector_private *vp, int budget);
7071

7172
/* Argument accessors to set variables (and/or set default values)
7273
* mtu, buffer sizing, default headroom, etc
@@ -77,7 +78,6 @@ static void vector_eth_configure(int n, struct arglist *def);
7778
#define DEFAULT_VECTOR_SIZE 64
7879
#define TX_SMALL_PACKET 128
7980
#define MAX_IOV_SIZE (MAX_SKB_FRAGS + 1)
80-
#define MAX_ITERATIONS 64
8181

8282
static const struct {
8383
const char string[ETH_GSTRING_LEN];
@@ -458,7 +458,6 @@ static int vector_send(struct vector_queue *qi)
458458
vp->estats.tx_queue_running_average =
459459
(vp->estats.tx_queue_running_average + result) >> 1;
460460
}
461-
netif_trans_update(qi->dev);
462461
netif_wake_queue(qi->dev);
463462
/* if TX is busy, break out of the send loop,
464463
* poll write IRQ will reschedule xmit for us
@@ -470,8 +469,6 @@ static int vector_send(struct vector_queue *qi)
470469
}
471470
}
472471
spin_unlock(&qi->head_lock);
473-
} else {
474-
tasklet_schedule(&vp->tx_poll);
475472
}
476473
return queue_depth;
477474
}
@@ -608,7 +605,7 @@ static struct vector_queue *create_queue(
608605

609606
/*
610607
* We do not use the RX queue as a proper wraparound queue for now
611-
* This is not necessary because the consumption via netif_rx()
608+
* This is not necessary because the consumption via napi_gro_receive()
612609
* happens in-line. While we can try using the return code of
613610
* netif_rx() for flow control there are no drivers doing this today.
614611
* For this RX specific use we ignore the tail/head locks and
@@ -896,7 +893,7 @@ static int vector_legacy_rx(struct vector_private *vp)
896893
skb->protocol = eth_type_trans(skb, skb->dev);
897894
vp->dev->stats.rx_bytes += skb->len;
898895
vp->dev->stats.rx_packets++;
899-
netif_rx(skb);
896+
napi_gro_receive(&vp->napi, skb);
900897
} else {
901898
dev_kfree_skb_irq(skb);
902899
}
@@ -955,7 +952,7 @@ static int writev_tx(struct vector_private *vp, struct sk_buff *skb)
955952
* mmsg vector matched to an skb vector which we prepared earlier.
956953
*/
957954

958-
static int vector_mmsg_rx(struct vector_private *vp)
955+
static int vector_mmsg_rx(struct vector_private *vp, int budget)
959956
{
960957
int packet_count, i;
961958
struct vector_queue *qi = vp->rx_queue;
@@ -972,6 +969,9 @@ static int vector_mmsg_rx(struct vector_private *vp)
972969

973970
/* Fire the Lazy Gun - get as many packets as we can in one go. */
974971

972+
if (budget > qi->max_depth)
973+
budget = qi->max_depth;
974+
975975
packet_count = uml_vector_recvmmsg(
976976
vp->fds->rx_fd, qi->mmsg_vector, qi->max_depth, 0);
977977

@@ -1021,7 +1021,7 @@ static int vector_mmsg_rx(struct vector_private *vp)
10211021
*/
10221022
vp->dev->stats.rx_bytes += skb->len;
10231023
vp->dev->stats.rx_packets++;
1024-
netif_rx(skb);
1024+
napi_gro_receive(&vp->napi, skb);
10251025
} else {
10261026
/* Overlay header too short to do anything - discard.
10271027
* We can actually keep this skb and reuse it,
@@ -1044,23 +1044,6 @@ static int vector_mmsg_rx(struct vector_private *vp)
10441044
return packet_count;
10451045
}
10461046

1047-
static void vector_rx(struct vector_private *vp)
1048-
{
1049-
int err;
1050-
int iter = 0;
1051-
1052-
if ((vp->options & VECTOR_RX) > 0)
1053-
while (((err = vector_mmsg_rx(vp)) > 0) && (iter < MAX_ITERATIONS))
1054-
iter++;
1055-
else
1056-
while (((err = vector_legacy_rx(vp)) > 0) && (iter < MAX_ITERATIONS))
1057-
iter++;
1058-
if ((err != 0) && net_ratelimit())
1059-
netdev_err(vp->dev, "vector_rx: error(%d)\n", err);
1060-
if (iter == MAX_ITERATIONS)
1061-
netdev_err(vp->dev, "vector_rx: device stuck, remote end may have closed the connection\n");
1062-
}
1063-
10641047
static int vector_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
10651048
{
10661049
struct vector_private *vp = netdev_priv(dev);
@@ -1085,25 +1068,15 @@ static int vector_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
10851068
netdev_sent_queue(vp->dev, skb->len);
10861069
queue_depth = vector_enqueue(vp->tx_queue, skb);
10871070

1088-
/* if the device queue is full, stop the upper layers and
1089-
* flush it.
1090-
*/
1091-
1092-
if (queue_depth >= vp->tx_queue->max_depth - 1) {
1093-
vp->estats.tx_kicks++;
1094-
netif_stop_queue(dev);
1095-
vector_send(vp->tx_queue);
1096-
return NETDEV_TX_OK;
1097-
}
1098-
if (netdev_xmit_more()) {
1071+
if (queue_depth < vp->tx_queue->max_depth && netdev_xmit_more()) {
10991072
mod_timer(&vp->tl, vp->coalesce);
11001073
return NETDEV_TX_OK;
1074+
} else {
1075+
queue_depth = vector_send(vp->tx_queue);
1076+
if (queue_depth > 0)
1077+
napi_schedule(&vp->napi);
11011078
}
1102-
if (skb->len < TX_SMALL_PACKET) {
1103-
vp->estats.tx_kicks++;
1104-
vector_send(vp->tx_queue);
1105-
} else
1106-
tasklet_schedule(&vp->tx_poll);
1079+
11071080
return NETDEV_TX_OK;
11081081
}
11091082

@@ -1114,7 +1087,7 @@ static irqreturn_t vector_rx_interrupt(int irq, void *dev_id)
11141087

11151088
if (!netif_running(dev))
11161089
return IRQ_NONE;
1117-
vector_rx(vp);
1090+
napi_schedule(&vp->napi);
11181091
return IRQ_HANDLED;
11191092

11201093
}
@@ -1133,8 +1106,7 @@ static irqreturn_t vector_tx_interrupt(int irq, void *dev_id)
11331106
* tweaking the IRQ mask less costly
11341107
*/
11351108

1136-
if (vp->in_write_poll)
1137-
tasklet_schedule(&vp->tx_poll);
1109+
napi_schedule(&vp->napi);
11381110
return IRQ_HANDLED;
11391111

11401112
}
@@ -1161,7 +1133,8 @@ static int vector_net_close(struct net_device *dev)
11611133
um_free_irq(vp->tx_irq, dev);
11621134
vp->tx_irq = 0;
11631135
}
1164-
tasklet_kill(&vp->tx_poll);
1136+
napi_disable(&vp->napi);
1137+
netif_napi_del(&vp->napi);
11651138
if (vp->fds->rx_fd > 0) {
11661139
if (vp->bpf)
11671140
uml_vector_detach_bpf(vp->fds->rx_fd, vp->bpf);
@@ -1193,15 +1166,32 @@ static int vector_net_close(struct net_device *dev)
11931166
return 0;
11941167
}
11951168

1196-
/* TX tasklet */
1197-
1198-
static void vector_tx_poll(struct tasklet_struct *t)
1169+
static int vector_poll(struct napi_struct *napi, int budget)
11991170
{
1200-
struct vector_private *vp = from_tasklet(vp, t, tx_poll);
1171+
struct vector_private *vp = container_of(napi, struct vector_private, napi);
1172+
int work_done = 0;
1173+
int err;
1174+
bool tx_enqueued = false;
12011175

1202-
vp->estats.tx_kicks++;
1203-
vector_send(vp->tx_queue);
1176+
if ((vp->options & VECTOR_TX) != 0)
1177+
tx_enqueued = (vector_send(vp->tx_queue) > 0);
1178+
if ((vp->options & VECTOR_RX) > 0)
1179+
err = vector_mmsg_rx(vp, budget);
1180+
else {
1181+
err = vector_legacy_rx(vp);
1182+
if (err > 0)
1183+
err = 1;
1184+
}
1185+
if (err > 0)
1186+
work_done += err;
1187+
1188+
if (tx_enqueued || err > 0)
1189+
napi_schedule(napi);
1190+
if (work_done < budget)
1191+
napi_complete_done(napi, work_done);
1192+
return work_done;
12041193
}
1194+
12051195
static void vector_reset_tx(struct work_struct *work)
12061196
{
12071197
struct vector_private *vp =
@@ -1265,6 +1255,9 @@ static int vector_net_open(struct net_device *dev)
12651255
goto out_close;
12661256
}
12671257

1258+
netif_napi_add(vp->dev, &vp->napi, vector_poll, get_depth(vp->parsed));
1259+
napi_enable(&vp->napi);
1260+
12681261
/* READ IRQ */
12691262
err = um_request_irq(
12701263
irq_rr + VECTOR_BASE_IRQ, vp->fds->rx_fd,
@@ -1306,15 +1299,15 @@ static int vector_net_open(struct net_device *dev)
13061299
uml_vector_attach_bpf(vp->fds->rx_fd, vp->bpf);
13071300

13081301
netif_start_queue(dev);
1302+
vector_reset_stats(vp);
13091303

13101304
/* clear buffer - it can happen that the host side of the interface
13111305
* is full when we get here. In this case, new data is never queued,
13121306
* SIGIOs never arrive, and the net never works.
13131307
*/
13141308

1315-
vector_rx(vp);
1309+
napi_schedule(&vp->napi);
13161310

1317-
vector_reset_stats(vp);
13181311
vdevice = find_device(vp->unit);
13191312
vdevice->opened = 1;
13201313

@@ -1543,15 +1536,16 @@ static const struct net_device_ops vector_netdev_ops = {
15431536
#endif
15441537
};
15451538

1546-
15471539
static void vector_timer_expire(struct timer_list *t)
15481540
{
15491541
struct vector_private *vp = from_timer(vp, t, tl);
15501542

15511543
vp->estats.tx_kicks++;
1552-
vector_send(vp->tx_queue);
1544+
napi_schedule(&vp->napi);
15531545
}
15541546

1547+
1548+
15551549
static void vector_eth_configure(
15561550
int n,
15571551
struct arglist *def
@@ -1634,7 +1628,6 @@ static void vector_eth_configure(
16341628
});
16351629

16361630
dev->features = dev->hw_features = (NETIF_F_SG | NETIF_F_FRAGLIST);
1637-
tasklet_setup(&vp->tx_poll, vector_tx_poll);
16381631
INIT_WORK(&vp->reset_tx, vector_reset_tx);
16391632

16401633
timer_setup(&vp->tl, vector_timer_expire, 0);

0 commit comments

Comments
 (0)