Bug 55595

Summary: 2.4.9-7 breaks kernel module interfaces for kiovec
Product: [Retired] Red Hat Linux Reporter: Douglas Miller <drmiller>
Component: kernelAssignee: Arjan van de Ven <arjanv>
Status: CLOSED NOTABUG QA Contact: Brock Organ <borgan>
Severity: high Docs Contact:
Priority: medium    
Version: 7.2CC: drmiller
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2001-11-02 18:31:17 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Douglas Miller 2001-11-02 17:43:13 UTC
From Bugzilla Helper:
User-Agent: Mozilla/4.77 [en] (X11; U; Linux 2.4.2-2 i686)

Description of problem:
The 2.4.9-7 kernel shipped with 7.2 breaks the interfaces for
alloc_kiovec/free_kiovec,
specifcally by removing the interfaces.  Granted, they are replaced by more
performant
interfaces but this still breaks any kernel modules that are not compiled,
and breaks
module compatability between the 2.4.7-10 kernel also shipped with 7.2.  A
better
approach would be to provide both interfaces.  Attached (addtnl info) is a
patch that does just that.

Version-Release number of selected component (if applicable):


How reproducible:
Always

Steps to Reproduce:
1. try to load a kernel module that uses all_kiovec on 2.4.9-7 kernel
2.
3.
	

Additional info:

diff -Nru linux-RH/fs/iobuf.c linux/fs/iobuf.c
--- linux-RH/fs/iobuf.c Fri Nov  2 08:25:27 2001
+++ linux/fs/iobuf.c    Fri Nov  2 08:44:24 2001
@@ -164,3 +164,41 @@
 }
 
 
+int alloc_kiovec(int nr, struct kiobuf **bufp)
+{
+       int i;
+       struct kiobuf *iobuf;
+
+       for (i = 0; i < nr; i++) {
+               iobuf = kmem_cache_alloc(kiobuf_cachep, SLAB_KERNEL);
+               if (!iobuf) {
+                       free_kiovec(i, bufp);
+                       return -ENOMEM;
+               }
+               kiobuf_init(iobuf);
+               if (alloc_kiobuf_bhs_sz(iobuf, KIO_MAX_SECTORS)) {
+                       kmem_cache_free(kiobuf_cachep, iobuf);
+                       free_kiovec(i, bufp);
+                       return -ENOMEM;
+               }
+               bufp[i] = iobuf;
+       }
+
+       return 0;
+}
+
+void free_kiovec(int nr, struct kiobuf **bufp) 
+{
+       int i;
+       struct kiobuf *iobuf;
+
+       for (i = 0; i < nr; i++) {
+               iobuf = bufp[i];
+               if (iobuf->locked)
+                       unlock_kiovec(1, &iobuf);
+               if (iobuf->array_len > KIO_STATIC_PAGES)
+                       kfree (iobuf->maplist);
+               free_kiobuf_bhs_sz(iobuf, KIO_MAX_SECTORS);
+               kmem_cache_free(kiobuf_cachep, bufp[i]);
+       }
+}
diff -Nru linux-RH/include/linux/iobuf.h linux/include/linux/iobuf.h
--- linux-RH/include/linux/iobuf.h      Fri Nov  2 08:25:27 2001
+++ linux/include/linux/iobuf.h Fri Nov  2 08:46:08 2001
@@ -73,6 +73,8 @@
 void   simple_wakeup_kiobuf(struct kiobuf *);
 int    alloc_kiovec_sz(int nr, struct kiobuf **, int *);
 void   free_kiovec_sz(int nr, struct kiobuf **, int *);
+int    alloc_kiovec(int nr, struct kiobuf **);
+void   free_kiovec(int nr, struct kiobuf **);
 int    expand_kiobuf(struct kiobuf *, int);
 void   kiobuf_wait_for_io(struct kiobuf *);
 extern int alloc_kiobuf_bhs(struct kiobuf *);
diff -Nru linux-RH/kernel/ksyms.c linux/kernel/ksyms.c
--- linux-RH/kernel/ksyms.c     Fri Nov  2 08:25:27 2001
+++ linux/kernel/ksyms.c        Fri Nov  2 08:46:31 2001
@@ -421,6 +421,8 @@
 /* Kiobufs */
 EXPORT_SYMBOL(alloc_kiovec_sz);
 EXPORT_SYMBOL(free_kiovec_sz);
+EXPORT_SYMBOL(alloc_kiovec);
+EXPORT_SYMBOL(free_kiovec);
 EXPORT_SYMBOL(expand_kiobuf);
 
 EXPORT_SYMBOL(map_user_kiobuf);

Comment 1 Arjan van de Ven 2001-11-02 17:52:55 UTC
No binary compatibility for kernel modules is guaranteed to work between
different kernels. In fact, I can guarantee you that you MUST recompile kernel
modules for different kernel versions.....

Comment 2 Tim Wright 2001-11-02 18:31:13 UTC
Ummm... 2 points.

This isn't a binary-only module issue - this is a source level incompatibility. You 
just deleted two public interfaces in an allegedly stable release (2.4.X), even 
though they weren't broken per se. This is generally considered "a bad thing"(TM).

Second, why were modversions added to the kernel and why do Red Hat ship with 
modversions enabled if you're supposed to rebuild modules for every different 
kernel ? It seems that they serve no useful purpose in that case.

Tim

Comment 3 Arjan van de Ven 2001-11-21 15:45:54 UTC
Re modversions: the primary reason for those is to prevent accentally loading
modules for the wrong kernel (say i386 modules into a i686 kernel).

Internal kernel interfaces have never been stable and probably never will be.
This was an upstream change and we try to mirror the upstream kernels. The
exported, stable, interfaces of the kernel (syscalls, ioctls and several /proc
files) are of course intended to be VERY non changing, and compatibility is
hardly ever broken.