Re: linux-2.3.31: drivers/char/drm/drmP.h does not allow 386 build

Rik Faith (faith@precisioninsight.com)
Fri, 10 Dec 1999 06:32:02 -0500 (EST)


On Thu 9 Dec 1999 06:59:19 -0500,
Rik Faith <faith@precisioninsight.com> wrote:
> On Thu 9 Dec 1999 12:29:15 +0100,
> Martin Mares <mj@suse.cz> wrote:
> > Hello,
> >
> > > The best solution is to modify the illegal instruction trap to
> > > emulate the missing insn on x86 via cli+sti. This would be useful
> > > from userland as well. It doesn't win speed awards, but it's easy
> > > correctness without punishing Real Computers.
> >
> > I've not looked at the code yet, but I guess it does use cmpxchg
> > to avoid races with card DMA, not with interrupts, hence cli+sti
> > won't help.
>
> There are actually two issues here.
>
> The first issue is how to implement a generic kernel-only cmpxchg routine.
> Obviously, you can implement this with cli+sti because all it requires is a
> critical section. You don't want to do that if you can avoid it, because
> it will be slow, and the only reason you want to use cmpxchg is for speed.
> However, if we want to make a functional cmpxchg routine for kernel-only
> use, that's fine.
>
> The other issue is how the DRM_LOCK makes use of cmpxchg. For performance
> reasons, the DRM_LOCK is shared between user-space and kernel-space, and
> the same locking that is done in the kernel must be done in user space.
> This allows a user-space processes to take and release the lock WITHOUT
> using an ioctl (the ioctl is only used in cases of contention -- all this
> is explained in detail in http://precisioninsight.com/dr/locking.html).
> Now, if we don't have a cmpxchg instruction that can be used or emulated
> from user-space, we can't do our efficient two-tiered locking. However, we
> can force all user-space processes to use the ioctl to take and release the
> DRM_LOCK all the time, even when there is no contention. This is a serious
> performance hit, so we don't want to do that on modern CPUs, but for the
> 386, which no one is going to use for direct-rendering anyway, it is a
> solution that provides functionality without performance. We don't need to
> implement that now, though, since we'll never run on a 386 -- I'm just
> noting that there is a possible pathway to a 386 solution in case anyone
> ever does want to run the DRI on a 386.
>
> For now, I think the best solution is that:
>
> 1) I change the drmP.h code to always compile with cmpxchg. We already
> guarantee that the DRI will never run on a 386, but I can also add
> code to the device driver's open routine so that it cannot be used
> on a 386 -- that will handle the case for all those 386s with PCI
> busses :)
>
> 2) Those interested implement the generic cmpxchg to work on 386
> processors, if there is a need. At this time, I don't think this
> work is justified unless someone else needs cmpxchg in the kernel.

Here are patches against 2.3.32-2 that implements #1 above. This allows
compilation of a 386 kernel that will run on a 386 with the DRM driver
unusable, but on non-386 Intel machines with the DRM driver usable.

--- linux/drivers/char/drm/drmP.h.rik Wed Dec 8 02:58:21 1999
+++ linux/drivers/char/drm/drmP.h Thu Dec 9 08:25:45 1999
@@ -116,7 +116,6 @@
#endif

/* Generic cmpxchg added in 2.3.x */
-#if CPU != 386
#ifndef __HAVE_ARCH_CMPXCHG
/* Include this here so that driver can be
used with older kernels. */
@@ -151,10 +150,6 @@
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \
(unsigned long)(n),sizeof(*(ptr))))
#endif
-#else
- /* Compiling for a 386 proper... */
-#error DRI not supported on Intel 80386
-#endif

/* Macros to make printk easier */
#define DRM_ERROR(fmt, arg...) \
@@ -468,6 +463,7 @@
/* Misc. support (init.c) */
extern int drm_flags;
extern void drm_parse_options(char *s);
+extern int drm_cpu_valid(void);


/* Device support (fops.c) */
--- linux/drivers/char/drm/init.c.rik Tue Dec 7 16:59:01 1999
+++ linux/drivers/char/drm/init.c Thu Dec 9 08:23:09 1999
@@ -97,3 +97,13 @@
}
}

+/* drm_cpu_valid returns non-zero if the DRI will run on this CPU, and 0
+ * otherwise. */
+
+int drm_cpu_valid(void)
+{
+#if defined(__i386__)
+ if (boot_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */
+#endif
+ return 1;
+}
--- linux/drivers/char/drm/fops.c.rik Tue Dec 7 16:59:01 1999
+++ linux/drivers/char/drm/fops.c Thu Dec 9 08:22:11 1999
@@ -40,6 +40,7 @@
drm_file_t *priv;

if (filp->f_flags & O_EXCL) return -EBUSY; /* No exclusive opens */
+ if (!drm_cpu_valid()) return -EINVAL;

DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/