Switch GEOM_DEV from make_dev_p() to make_dev_s().
It closes the race condition and so allows to remove few NULL checks. Also while there, use dev->si_drv1 in addition to cp->private to store softc pointer. For calls coming from the dev side it gives reliable cache hit instead of often miss before. MFC after: 2 weeks Sponsored by: iXsystems, Inc.
This commit is contained in:
parent
2b289d0bff
commit
e61ed7983e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=355410
@ -334,6 +334,7 @@ g_dev_taste(struct g_class *mp, struct g_provider *pp, int insist __unused)
|
||||
int error;
|
||||
struct cdev *dev, *adev;
|
||||
char buf[SPECNAMELEN + 6];
|
||||
struct make_dev_args args;
|
||||
|
||||
g_trace(G_T_TOPOLOGY, "dev_taste(%s,%s)", mp->name, pp->name);
|
||||
g_topology_assert();
|
||||
@ -346,8 +347,17 @@ g_dev_taste(struct g_class *mp, struct g_provider *pp, int insist __unused)
|
||||
error = g_attach(cp, pp);
|
||||
KASSERT(error == 0,
|
||||
("g_dev_taste(%s) failed to g_attach, err=%d", pp->name, error));
|
||||
error = make_dev_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK, &dev,
|
||||
&g_dev_cdevsw, NULL, UID_ROOT, GID_OPERATOR, 0640, "%s", gp->name);
|
||||
|
||||
make_dev_args_init(&args);
|
||||
args.mda_flags = MAKEDEV_CHECKNAME | MAKEDEV_WAITOK;
|
||||
args.mda_devsw = &g_dev_cdevsw;
|
||||
args.mda_cr = NULL;
|
||||
args.mda_uid = UID_ROOT;
|
||||
args.mda_gid = GID_OPERATOR;
|
||||
args.mda_mode = 0640;
|
||||
args.mda_si_drv1 = sc;
|
||||
args.mda_si_drv2 = cp;
|
||||
error = make_dev_s(&args, &sc->sc_dev, "%s", gp->name);
|
||||
if (error != 0) {
|
||||
printf("%s: make_dev_p() failed (gp->name=%s, error=%d)\n",
|
||||
__func__, gp->name, error);
|
||||
@ -358,11 +368,9 @@ g_dev_taste(struct g_class *mp, struct g_provider *pp, int insist __unused)
|
||||
g_free(sc);
|
||||
return (NULL);
|
||||
}
|
||||
dev = sc->sc_dev;
|
||||
dev->si_flags |= SI_UNMAPPED;
|
||||
sc->sc_dev = dev;
|
||||
|
||||
dev->si_iosize_max = MAXPHYS;
|
||||
dev->si_drv2 = cp;
|
||||
error = init_dumpdev(dev);
|
||||
if (error != 0)
|
||||
printf("%s: init_dumpdev() failed (gp->name=%s, error=%d)\n",
|
||||
@ -397,8 +405,6 @@ g_dev_open(struct cdev *dev, int flags, int fmt, struct thread *td)
|
||||
int error, r, w, e;
|
||||
|
||||
cp = dev->si_drv2;
|
||||
if (cp == NULL)
|
||||
return (ENXIO); /* g_dev_taste() not done yet */
|
||||
g_trace(G_T_ACCESS, "g_dev_open(%s, %d, %d, %p)",
|
||||
cp->geom->name, flags, fmt, td);
|
||||
|
||||
@ -429,7 +435,7 @@ g_dev_open(struct cdev *dev, int flags, int fmt, struct thread *td)
|
||||
error = g_access(cp, r, w, e);
|
||||
g_topology_unlock();
|
||||
if (error == 0) {
|
||||
sc = cp->private;
|
||||
sc = dev->si_drv1;
|
||||
mtx_lock(&sc->sc_mtx);
|
||||
if (sc->sc_open == 0 && (sc->sc_active & SC_A_ACTIVE) != 0)
|
||||
wakeup(&sc->sc_active);
|
||||
@ -451,8 +457,6 @@ g_dev_close(struct cdev *dev, int flags, int fmt, struct thread *td)
|
||||
int error, r, w, e;
|
||||
|
||||
cp = dev->si_drv2;
|
||||
if (cp == NULL)
|
||||
return (ENXIO);
|
||||
g_trace(G_T_ACCESS, "g_dev_close(%s, %d, %d, %p)",
|
||||
cp->geom->name, flags, fmt, td);
|
||||
|
||||
@ -477,7 +481,7 @@ g_dev_close(struct cdev *dev, int flags, int fmt, struct thread *td)
|
||||
if (r + w + e == 0)
|
||||
return (EINVAL);
|
||||
|
||||
sc = cp->private;
|
||||
sc = dev->si_drv1;
|
||||
mtx_lock(&sc->sc_mtx);
|
||||
sc->sc_open += r + w + e;
|
||||
if (sc->sc_open == 0)
|
||||
@ -797,7 +801,6 @@ g_dev_strategy(struct bio *bp)
|
||||
("Wrong bio_cmd bio=%p cmd=%d", bp, bp->bio_cmd));
|
||||
dev = bp->bio_dev;
|
||||
cp = dev->si_drv2;
|
||||
sc = cp->private;
|
||||
KASSERT(cp->acr || cp->acw,
|
||||
("Consumer with zero access count in g_dev_strategy"));
|
||||
biotrack(bp, __func__);
|
||||
@ -809,6 +812,7 @@ g_dev_strategy(struct bio *bp)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
sc = dev->si_drv1;
|
||||
KASSERT(sc->sc_open > 0, ("Closed device in g_dev_strategy"));
|
||||
atomic_add_int(&sc->sc_active, 1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user