Re: DRM map design
Dave Airlie writes: I've made a patch against the DRM code in CVS adding a few pieces that were missing. The code works for me on both radeon and r128. I've also tried to test mga however the mga code in CVS doesn't seem to work at all right now. My guess would be idr's changes might need some compat work .. no idea though.. I didn't see any problems. mga client side needs two adjustments. One really is a bugfix in code that isn't used with newer versions of DRM and the other one is a fix to the DRIRec structure. We may be able to do some compat work there but I'm not sure if it's worth it. We have already discussed eliminating drmAddress. These changes can be done simultaniously. I am currently assigning completely arbitrary 32-bit tokens for maps just to see how that works, and it seems to be fine on my G5 (which has AGP and a radeon 9600 card). I think it would be preferable to use Egbert's code which uses the map-offset value if it fits into 32 bits in the longer term. I've changed this to use the address value if possible (if it fits into 32bits and if the value has not been used as token for something else). This should help to maintain backward compatibility, on the other hand it may not sufficiently deter people from using handles as base addresses. DRM will work with either version. The kernel does not use drm_handle_t (except for the mga driver) where the use of it has been introduced just recently. I only consider published kernels and released X as stable ABIs so we can change the kernel stuff for the mga now... its in -mm but that is only experimental.. OK, how should we proceed then? I would propose the following: Phase 1: a. Make changes to DRM but leave drm_handle_t unsigned long We could then make texture_handle u32 as this would suffice to hold all significant bits of drm_handle_t although drm_handle_t is still unsigned long. b. convert unsigned long handle to drm_handle_t handle in Mesa and X code. Phase 2: a. change drm_handle_t to unsigned int. b. eliminate drmAddress and make the appropriate changes to driver DRIRec structures in Mesa and X. I can commit all the changes to X. However since some code (the driver DRI files for example) live both in Mesa and X things need to be coordinated somewhat. Can anyone give me a clue how this coordination is done? Cheers, Egbert. --- This SF.Net email is sponsored by the 'Do More With Dual!' webinar happening July 14 at 8am PDT/11am EDT. We invite you to explore the latest in dual core and dual graphics technology at this free one hour event hosted by HP, AMD, and NVIDIA. To register visit http://www.hp.com/go/dualwebinar -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
I've made a patch against the DRM code in CVS adding a few pieces that were missing. The code works for me on both radeon and r128. I've also tried to test mga however the mga code in CVS doesn't seem to work at all right now. My guess would be idr's changes might need some compat work .. no idea though.. I am currently assigning completely arbitrary 32-bit tokens for maps just to see how that works, and it seems to be fine on my G5 (which has AGP and a radeon 9600 card). I think it would be preferable to use Egbert's code which uses the map-offset value if it fits into 32 bits in the longer term. I've changed this to use the address value if possible (if it fits into 32bits and if the value has not been used as token for something else). This should help to maintain backward compatibility, on the other hand it may not sufficiently deter people from using handles as base addresses. DRM will work with either version. The kernel does not use drm_handle_t (except for the mga driver) where the use of it has been introduced just recently. I only consider published kernels and released X as stable ABIs so we can change the kernel stuff for the mga now... its in -mm but that is only experimental.. Dave. -- David Airlie, Software Engineer http://www.skynet.ie/~airlied / airlied at skynet.ie Linux kernel - DRI, VAX / pam_smb / ILUG --- This SF.Net email is sponsored by the 'Do More With Dual!' webinar happening July 14 at 8am PDT/11am EDT. We invite you to explore the latest in dual core and dual graphics technology at this free one hour event hosted by HP, AMD, and NVIDIA. To register visit http://www.hp.com/go/dualwebinar -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
Keith Whitwell writes: Sounds good Paul. I think it's worthwhile to at least investigate this as it'd be a cleaner result all round at the end. Based on Egbert's comments about the use of an idr structure restricting our choice of token values, I have taken an alternative approach where I put the user token in the drm_map_list_t structure, which is private to the kernel. This patch is against the current DRM code in the kernel tree. The DRM code in CVS looks a bit different and I'm not sure where it is up to. I am currently assigning completely arbitrary 32-bit tokens for maps just to see how that works, and it seems to be fine on my G5 (which has AGP and a radeon 9600 card). I think it would be preferable to use Egbert's code which uses the map-offset value if it fits into 32 bits in the longer term. I am also assigning 32-bit tokens even if CONFIG_COMPAT isn't defined. For 64-bit kernels that don't have CONFIG_COMPAT defined, do we still want to generate 32-bit tokens? We will have to if we make the tokens passed between the X server and the client 32-bit. If people don't like me adding the dev-agp_buffer_token field, the alternative would be to search the dev-maplist list to find the token for dev-agp_buffer_list in drm_mapbufs. I didn't see the point in throwing away the token and then having to search for it, though. I have incorporated the drm_core_findmap_by_base from Egbert's patch. Nothing in the kernel tree's DRM seems to need it at present. Comments? Paul. diff -urN linux-2.6/drivers/char/drm/drmP.h g5-ppc64-drm/drivers/char/drm/drmP.h --- linux-2.6/drivers/char/drm/drmP.h 2005-06-27 13:26:27.0 +1000 +++ g5-ppc64-drm/drivers/char/drm/drmP.h2005-07-04 08:56:35.0 +1000 @@ -531,6 +531,7 @@ typedef struct drm_map_list { struct list_headhead; /** list head */ drm_map_t *map; /** mapping */ + unsigned intuser_token; } drm_map_list_t; typedef drm_map_t drm_local_map_t; @@ -736,6 +737,7 @@ structdrm_driver *driver; drm_local_map_t *agp_buffer_map; + unsigned int agp_buffer_token; drm_head_t primary; /** primary screen head */ } drm_device_t; @@ -1035,16 +1037,23 @@ drm_ioremapfree( map-handle, map-size, dev ); } -static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned long offset) +static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned int token) { - struct list_head *_list; - list_for_each( _list, dev-maplist-head ) { - drm_map_list_t *_entry = list_entry( _list, drm_map_list_t, head ); - if ( _entry-map -_entry-map-offset == offset ) { + drm_map_list_t *_entry; + + list_for_each_entry(_entry, dev-maplist-head, head) + if (_entry-user_token == token) + return _entry-map; + return NULL; +} + +static __inline__ struct drm_map *drm_core_findmap_by_base(struct drm_device *dev, unsigned long offset) +{ + drm_map_list_t *_entry; + + list_for_each_entry(_entry, dev-maplist-head, head) + if (_entry-map _entry-map-offset == offset) return _entry-map; - } - } return NULL; } diff -urN linux-2.6/drivers/char/drm/drm_bufs.c g5-ppc64-drm/drivers/char/drm/drm_bufs.c --- linux-2.6/drivers/char/drm/drm_bufs.c 2005-06-27 13:26:27.0 +1000 +++ g5-ppc64-drm/drivers/char/drm/drm_bufs.c2005-07-04 10:43:39.0 +1000 @@ -60,14 +60,10 @@ } EXPORT_SYMBOL(drm_order); -#ifdef CONFIG_COMPAT /* - * Used to allocate 32-bit handles for _DRM_SHM regions - * The 0x1000 value is chosen to be out of the way of - * FB/register and GART physical addresses. + * Used to allocate 32-bit handles for mappings. */ static unsigned int map32_handle = 0x1000; -#endif /** * Ioctl to specify a range of memory that is available for mapping by a non-root process. @@ -90,6 +86,7 @@ drm_map_t *map; drm_map_t __user *argp = (void __user *)arg; drm_map_list_t *list; + unsigned long handle; if ( !(filp-f_mode 3) ) return -EACCES; /* Require read/write */ @@ -196,17 +193,16 @@ down(dev-struct_sem); list_add(list-head, dev-maplist-head); -#ifdef CONFIG_COMPAT - /* Assign a 32-bit handle for _DRM_SHM mappings */ + + /* Assign a 32-bit handle */ /* We do it here so that dev-struct_sem protects the increment */ - if (map-type == _DRM_SHM) - map-offset = map32_handle += PAGE_SIZE; -#endif + list-user_token = handle = map32_handle += PAGE_SIZE; + up(dev-struct_sem); if ( copy_to_user( argp, map, sizeof(*map) ) ) return -EFAULT; - if (copy_to_user(argp-handle, map-offset, sizeof(map-offset))) + if (put_user(handle,
Re: DRM map design
Jon Smirl writes: drmMap never cares about the handle since drmMap turns into mmap and mmap doesn't know about DRM maps. Huh? drm_mmap certainly does know about DRM maps. The trouble with using the offset returned by drmGetMap is that if your program is a 32-bit program running on a 64-bit kernel, and the kernel map-offset value for the map you want is 4G, then your 32-bit program will only see the bottom 32 bits of the offset value, and you end up with no way for your 32-bit program to mmap the map. That's why I am suggesting that the kernel should create a 32-bit token for each map and return it in the handle field, and the program should use that as the mmap offset when mmapping the map. Paul. --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477alloc_id=16492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
On 7/3/05, Paul Mackerras [EMAIL PROTECTED] wrote: Jon Smirl writes: drmMap never cares about the handle since drmMap turns into mmap and mmap doesn't know about DRM maps. Huh? drm_mmap certainly does know about DRM maps. I see now that drmMap is overriding mmap's offset to pass in the handle. So the reason my code is working is that the DRM handle and offset are currently the same number. int drmMap(int fd, drm_handle_t handle, drmSize size, drmAddressPtr address) { static unsigned long pagesize_mask = 0; if (fd 0) return -EINVAL; if (!pagesize_mask) pagesize_mask = getpagesize() - 1; size = (size + pagesize_mask) ~pagesize_mask; *address = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle); if (*address == MAP_FAILED) return -errno; return 0; } I had switched to using offset since sarea had a handle of zero. A handle of zero doesn't work because it trips this code at the beginning of drm_mmap. int drm_mmap(struct file *filp, struct vm_area_struct *vma) { DRM_DEBUG(start = 0x%lx, end = 0x%lx, offset = 0x%lx\n, vma-vm_start, vma-vm_end, VM_OFFSET(vma)); if (!priv-authenticated) return -EACCES; /* We check for dma. On Apple's UniNorth, it's valid to have * the AGP mapped at physical address 0 * --BenH. */ if (!VM_OFFSET(vma) #if __OS_HAS_AGP (!dev-agp || dev-agp-agp_info.device-vendor != PCI_VENDOR_ID_APPLE) #endif ) return drm_mmap_dma(filp, vma); When I passed in sarea's handle I was ending up in drm_mmap_dma. The trouble with using the offset returned by drmGetMap is that if your program is a 32-bit program running on a 64-bit kernel, and the kernel map-offset value for the map you want is 4G, then your 32-bit program will only see the bottom 32 bits of the offset value, and you end up with no way for your 32-bit program to mmap the map. That's why I am suggesting that the kernel should create a 32-bit token for each map and return it in the handle field, and the program should use that as the mmap offset when mmapping the map. I'm fine with switching to true handles. I'm not really sure what the check for 'dma' is looking for. But we need to fix sarea to have a proper handle. -- Jon Smirl [EMAIL PROTECTED] --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_idt77alloc_id492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
Keith Whitwell writes: In general I'd prefer that the values passed to clients (and back again) to be abstract tokens rather than actual addresses or offsets into some unspecified address space. Which should mean that 32 bits is more than ample to contain them... The problem that we have is that currently the kernel DRM uses the map-offset field for two different things: (a) as a token for userspace to use to identify a particular map and (b) to store map-type-specific information such as the physical address for _DRM_REGISTERS and _DRM_FRAME_BUFFER maps, or the address within the GART aperture for _DRM_AGP maps, or the kernel virtual address within a scatter/gather mapping for _DRM_SCATTER_GATHER maps. For _DRM_SHM maps, map-offset is set to the kernel virtual address of the memory allocated for the map, but that is only used as a token, not for internal use inside the DRM. In fact it is only by luck that we don't get collisions between the physical addresses used for _DRM_REGISTERS and _DRM_FRAME_BUFFER maps and the kernel virtual addresses used for _DRM_SHM maps at the moment. My patch took the approach of only creating abstract tokens for _DRM_SHM maps, which meant that I didn't need to disentangle (a) and (b). If we are going to create abstract tokens for all maps, we need to do something different. One alternative is to add another field to the kernel's (i.e. the DRM's) version of the drm_map_t, in which to store the userspace token. This is the approach taken by Egbert's patch. The current version of Egbert's patch has the kernel version of the drm_map_t called the same but different from the userspace drm_map_t. I would prefer that the kernel structure be called something different if its contents are different, but that will admittedly make the patch pretty intrusive. Another alternative is to have a separate data structure to translate userspace tokens to drm_map_t pointers. The idr structure in the kernel (include/linux/idr.h) is commonly used for this sort of thing. With this approach, we would allocate map handles as small multiples of PAGE_SIZE, and use idr_find(dev-map_idr, handle PAGE_SHIFT) to map from userspace tokens to drm_map_t *'s. I believe we don't ever need to go from drm_map_t * to the userspace token. I'll try to code this up over the weekend so that we can see how intrusive it is likely to be. The advantage is of course that it means we don't have to have different drm_map_t's in the kernel and userspace. Paul. --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477alloc_id=16492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
Paul Mackerras wrote: Keith Whitwell writes: In general I'd prefer that the values passed to clients (and back again) to be abstract tokens rather than actual addresses or offsets into some unspecified address space. Which should mean that 32 bits is more than ample to contain them... The problem that we have is that currently the kernel DRM uses the map-offset field for two different things: (a) as a token for userspace to use to identify a particular map and (b) to store map-type-specific information such as the physical address for _DRM_REGISTERS and _DRM_FRAME_BUFFER maps, or the address within the GART aperture for _DRM_AGP maps, or the kernel virtual address within a scatter/gather mapping for _DRM_SCATTER_GATHER maps. For _DRM_SHM maps, map-offset is set to the kernel virtual address of the memory allocated for the map, but that is only used as a token, not for internal use inside the DRM. In fact it is only by luck that we don't get collisions between the physical addresses used for _DRM_REGISTERS and _DRM_FRAME_BUFFER maps and the kernel virtual addresses used for _DRM_SHM maps at the moment. My patch took the approach of only creating abstract tokens for _DRM_SHM maps, which meant that I didn't need to disentangle (a) and (b). If we are going to create abstract tokens for all maps, we need to do something different. One alternative is to add another field to the kernel's (i.e. the DRM's) version of the drm_map_t, in which to store the userspace token. This is the approach taken by Egbert's patch. The current version of Egbert's patch has the kernel version of the drm_map_t called the same but different from the userspace drm_map_t. I would prefer that the kernel structure be called something different if its contents are different, but that will admittedly make the patch pretty intrusive. Another alternative is to have a separate data structure to translate userspace tokens to drm_map_t pointers. The idr structure in the kernel (include/linux/idr.h) is commonly used for this sort of thing. With this approach, we would allocate map handles as small multiples of PAGE_SIZE, and use idr_find(dev-map_idr, handle PAGE_SHIFT) to map from userspace tokens to drm_map_t *'s. I believe we don't ever need to go from drm_map_t * to the userspace token. I'll try to code this up over the weekend so that we can see how intrusive it is likely to be. The advantage is of course that it means we don't have to have different drm_map_t's in the kernel and userspace. Sounds good Paul. I think it's worthwhile to at least investigate this as it'd be a cleaner result all round at the end. Keith --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477alloc_id=16492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
Paul Mackerras writes: Keith Whitwell writes: In general I'd prefer that the values passed to clients (and back again) to be abstract tokens rather than actual addresses or offsets into some unspecified address space. Which should mean that 32 bits is more than ample to contain them... The problem that we have is that currently the kernel DRM uses the map-offset field for two different things: (a) as a token for userspace to use to identify a particular map and (b) to store map-type-specific information such as the physical address for _DRM_REGISTERS and _DRM_FRAME_BUFFER maps, or the address within the GART aperture for _DRM_AGP maps, or the kernel virtual address within a scatter/gather mapping for _DRM_SCATTER_GATHER maps. For _DRM_SHM maps, map-offset is set to the kernel virtual address of the memory allocated for the map, but that is only used as a token, not for internal use inside the DRM. In fact it is only by luck that we don't get collisions between the physical addresses used for _DRM_REGISTERS and _DRM_FRAME_BUFFER maps and the kernel virtual addresses used for _DRM_SHM maps at the moment. My patch took the approach of only creating abstract tokens for _DRM_SHM maps, which meant that I didn't need to disentangle (a) and (b). If we are going to create abstract tokens for all maps, we need to do something different. One alternative is to add another field to the kernel's (i.e. the DRM's) version of the drm_map_t, in which to store the userspace token. This is the approach taken by Egbert's patch. The current version of Egbert's patch has the kernel version of the drm_map_t called the same but different from the userspace drm_map_t. I would prefer that the kernel structure be called something different if its contents are different, but that will admittedly make the patch pretty intrusive. That's fine. This can be done, it will just make the patch bigger, which should be less of a concern than future confusion. Another alternative is to have a separate data structure to translate userspace tokens to drm_map_t pointers. The idr structure in the kernel (include/linux/idr.h) is commonly used for this sort of thing. With this approach, we would allocate map handles as small multiples of PAGE_SIZE, and use idr_find(dev-map_idr, handle PAGE_SHIFT) to map from userspace tokens to drm_map_t *'s. I believe we don't ever need to go from drm_map_t * to the userspace token. I'll try to code this up over the weekend so that we can see how intrusive it is likely to be. The advantage is of course that it means we don't have to have different drm_map_t's in the kernel and userspace. Well, both approaches are fine. The disadvantage of the second apporach however is that we have no control over the token value. Therefore we cannot take the gentle approach to make the attempt to leave values that fit into 32bit unchanged. This would definitely change the kernel ABI and may have side effects for some exisiting drivers - especially binary only drivers. Egbert. --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477alloc_id=16492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
Don't the maps always contain the physical address of the object? That would provide a unique handle. Where does the handle get used in user space? After I GetMap() to find the map I need, I pass the offset back into drmMap() not the handle. Offset is the physical address in most cases. -- Jon Smirl [EMAIL PROTECTED] --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_idt77alloc_id492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
Jon Smirl writes: Don't the maps always contain the physical address of the object? That would provide a unique handle. No, for _DRM_SHM and _DRM_SCATTER_GATHER maps the offset is a kernel virtual address (at least at present). It's only by luck that we don't see collisions. Also, using a physical address is not suitable in the long term if we want 32-bit handles, since physical addresses may well be above 4GB in future, though for now most systems that we care about seem to put their AGP and PCI devices at physical addresses below 4GB. Where does the handle get used in user space? After I GetMap() to find the map I need, I pass the offset back into drmMap() not the handle. Offset is the physical address in most cases. There is a confusing inconsistency between drm_addmap and drm_getmap here. drm_addmap has code at the end to return the kernel's map-offset value in the userspace map-handle field, but drm_getmap doesn't do that. So yes, using the map-offset returned by drmGetMap is correct, at least at present. That's unfortunate, though, because if we go to 32-bit handles, we'd really want drm_getmap to return the handle in *handle rather than *offset, which would mean that it would be the handle value that you would have to pass to mmap, rather than the offset value. It seems that nothing in X or DRI currently uses drmGetMap except for test/dristat.c, which only prints the offset and handle, so presumably your stuff would be the only thing that broke if we changed this. :) Paul. --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477alloc_id=16492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
I've attached my current diffs to DRM. I am coverting DRM so that the server does not have to run as root. The attached code allows this. Most of the changes are in AddMap. 1) sarea is prebuilt 2) agp maps are allowed from non-root master but checked to make sure they are within allocated agp space. 3) I haven't done PCI maps yet they will look like the AGP ones. I will probaby get rid of the changes where I added an extra parameter to the IOCTL macros before check in. From user space I use loops like this: for (i = 0;; i++) { if (drmGetMap(disp-drmFD, i, offset, size, type, flags, handle, mtrr) != 0) break; if (type == DRM_SHM) { if (drmMap( disp-drmFD, offset, size, (drmAddressPtr)(disp-pSAREA)) 0) { fprintf(stderr, [drm] drmMap failed\n); return 0; } break; } } if (!disp-pSAREA) return 0; drmMap never cares about the handle since drmMap turns into mmap and mmap doesn't know about DRM maps. -- Jon Smirl [EMAIL PROTECTED] patch Description: Binary data
Re: DRM map design
Paul Mackerras wrote: Do either of you (or does anyone) have a good mental grasp of how map handles and offsets are used and manipulated in the X server and in DRI clients? In particular, I'm interested to know under what circumstances map handles are generated by arithmetic on other map handles, or obtained from a source other than a DRM_IOCTL_ADD_MAP ioctl. Similarly for the offset in a mmap on /dev/dri/cardN; do we do arithmetic to get those values? The underlying question is to what extent the handle returned by DRM_IOCTL_ADD_MAP needs to be predictable (or have a predictable relationship to other handles) rather than just being an arbitrary token invented by the kernel DRM code. In general I'd prefer that the values passed to clients (and back again) to be abstract tokens rather than actual addresses or offsets into some unspecified address space. Which should mean that 32 bits is more than ample to contain them... Keith --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477alloc_id=16492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
Hi! On 6/28/05, Ian Romanick [EMAIL PROTECTED] wrote: 3) Can the driver pre-build the AGP/PCI gart maps? If these maps are marked differently it is way for my driver to tell AGP from PCI cards. I would advise against that. There are (rare) cases where user-mode wants to select AGP parameters, AGP mode vs. PCI mode, etc. If AGP is acquired and those maps added at module load, the only way to make those selections will be via module paramters. Yuck. Currently the drivers are AddMap'ing multiple little maps over the AGP area, but the area is basically split into two area: private for the master and public for the DRI clients to write to. So to get around the root priv requirement of AddMap I could have DRM initially create a map which only allows master access to AGP space. Then the non-root master could safely AddMap sub-maps which must exist inside of the predefined AGP map. These sub-maps would lower the priv requirements for parts of AGP space and allow the clients to run. The via drm module needs a kernel 2MB _RESTRICTED AGP map for the command stream. The master must not have access to that part, since it will allow a non-root master to modify the command stream once it has been security-checked. How will drmAgpAlloc be handled? I mean, how will DRM know how big the initial map will be? /Thomas -- Jon Smirl [EMAIL PROTECTED] --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_idt77alloc_id492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_idt77alloc_id492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
Do either of you (or does anyone) have a good mental grasp of how map handles and offsets are used and manipulated in the X server and in DRI clients? In particular, I'm interested to know under what circumstances map handles are generated by arithmetic on other map handles, or obtained from a source other than a DRM_IOCTL_ADD_MAP ioctl. Similarly for the offset in a mmap on /dev/dri/cardN; do we do arithmetic to get those values? The underlying question is to what extent the handle returned by DRM_IOCTL_ADD_MAP needs to be predictable (or have a predictable relationship to other handles) rather than just being an arbitrary token invented by the kernel DRM code. Thanks, Paul. --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477alloc_id=16492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
On 6/29/05, Thomas Hellström [EMAIL PROTECTED] wrote: Currently the drivers are AddMap'ing multiple little maps over the AGP area, but the area is basically split into two area: private for the master and public for the DRI clients to write to. So to get around the root priv requirement of AddMap I could have DRM initially create a map which only allows master access to AGP space. Then the non-root master could safely AddMap sub-maps which must exist inside of the predefined AGP map. These sub-maps would lower the priv requirements for parts of AGP space and allow the clients to run. The via drm module needs a kernel 2MB _RESTRICTED AGP map for the command stream. The master must not have access to that part, since it will allow a non-root master to modify the command stream once it has been security-checked. How will drmAgpAlloc be handled? I mean, how will DRM know how big the initial map will be? drmAgpAlloc() allocs drm_agp_mem structures which track the agp allocs. I could change the map system to allow a single map to be paired with each struct drm_agp_mem. The 2MB restricted you are using was allocated with a call to drmAgpAlloc(), right? You would then add a _RESTRICTED map which would bind to the struct drm_agp_mem and stop further maps. We need to a check to make sure a normal user can't free and reallocate a piece of AGP memory marked restricted. The drivers would then be changed to alloc the various parts of AGP space instead of allocing one big chunk and carving it up. By allocing multiple pieces the master can set different privs on each piece. Backwards compatibility is maintained since root can make any maps that it wants ignoring the one map per struct drm_agp_mem restriction. -- Jon Smirl [EMAIL PROTECTED] --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_idt77alloc_id492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
On 6/29/05, Paul Mackerras [EMAIL PROTECTED] wrote: Do either of you (or does anyone) have a good mental grasp of how map handles and offsets are used and manipulated in the X server and in DRI clients? In particular, I'm interested to know under what circumstances map handles are generated by arithmetic on other map handles, or obtained from a source other than a DRM_IOCTL_ADD_MAP ioctl. Similarly for the offset in a mmap on /dev/dri/cardN; do we do arithmetic to get those values? The underlying question is to what extent the handle returned by DRM_IOCTL_ADD_MAP needs to be predictable (or have a predictable relationship to other handles) rather than just being an arbitrary token invented by the kernel DRM code. I don't think that map handles are being computed in any uniform way. Sometimes they are zero, sometimes the physical address, sometime the kernel virtual address. I'm not clear on what user space is supposed to do with handles. I'm doing drmGet(), getting the offset and then passing the offset back into drmMap(). I just ran into a problem where the handle for the framebuffer was zero and that won't work with drmMap(). After changing to the offset field I am just ignoring the handles. -- Jon Smirl [EMAIL PROTECTED] --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_idt77alloc_id492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
On 6/29/05, Jon Smirl [EMAIL PROTECTED] wrote: drmAgpAlloc() allocs drm_agp_mem structures which track the agp allocs. I could change the map system to allow a single map to be paired with each struct drm_agp_mem. The 2MB restricted you are using was allocated with a call to drmAgpAlloc(), right? You would then add a _RESTRICTED map which would bind to the struct drm_agp_mem and stop further maps. We need to a check to make sure a normal user can't free and reallocate a piece of AGP memory marked restricted. The drivers would then be changed to alloc the various parts of AGP space instead of allocing one big chunk and carving it up. By allocing multiple pieces the master can set different privs on each piece. Backwards compatibility is maintained since root can make any maps that it wants ignoring the one map per struct drm_agp_mem restriction. A better scheme to do this might be to leave drmAddMap alone and create a new DRM entry point drmAgpAllocMap(). drmAddMap() would continue to be root only. drmAgpAllocMap() is derived from drmAgpAlloc() but also builds a map entry spanning the agp space allocated. It takes an additional parameter for the appropriate DRM_MAP flags. drmAgpAllocMap() would be marked master-only, not root-only. I believe this would be a better approach than changing drmAddMap to allow some maps to be added without root priv and others still needing it. drmAgpAllocMap() already has all of the info it needs, it is easy for it to make the map too. -- Jon Smirl [EMAIL PROTECTED] --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_idt77alloc_id492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
DRM map design
We should discuss the design of DRM maps so that we don't work at cross purposes. I have a new requirement coming from the egl-driver work that my user space driver does not have root priv so it can't create the maps. This implies that the drivers need to pre-create the maps. To access the maps I rely on doing GetMap and searching for the map I need. My driver does not have the info needed to create the maps even if it had the privs. I have never liked how user space needs to figure out a bunch of info about the hardware and them tell it to the device driver since the device driver obviously already knows all of the info it is being told. The register map should be marked read only or root only. I don't need access to the register map. 1) Should the maps be created once at driver load time or on open/close? I can probably make the egl drivers work either way. 2) Is compatibility maintained by doing a match in AddMap and then returning the matching map? 3) Can the driver pre-build the AGP/PCI gart maps? If these maps are marked differently it is way for my driver to tell AGP from PCI cards. 4) Are there issues with sarea other than the one we talked about with XvMC? 5) I had set things up so that a reset program could access the register/framebuffer maps before the card was initialized. You need that because you can't initialize a card that hasn't been reset. BenH is working on another reset scheme so this may not be needed any more. 6) Is there some need for user space collecting info about the hardware and then feeding it back into the driver that I can't see? 7) Any more issues? -- Jon Smirl [EMAIL PROTECTED] --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_idt77alloc_id492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Jon Smirl wrote: We should discuss the design of DRM maps so that we don't work at cross purposes. I have a new requirement coming from the egl-driver work that my user space driver does not have root priv so it can't create the maps. This implies that the drivers need to pre-create the maps. To access the maps I rely on doing GetMap and searching for the map I need. My driver does not have the info needed to create the maps even if it had the privs. I have never liked how user space needs to figure out a bunch of info about the hardware and them tell it to the device driver since the device driver obviously already knows all of the info it is being told. The register map should be marked read only or root only. I don't need access to the register map. 1) Should the maps be created once at driver load time or on open/close? I can probably make the egl drivers work either way. I did it at neither time in the MGA driver. When I added support there for PCI cards, I added a DMA boot-strap ioctl. User-mode passes in some parameters to the kernel (e.g., size of DMA buffers, requested AGP mode, etc.). The kernel then uses those parameters as guidelines to initialize itself. Any changes the kernel has to make (e.g., 4x AGP was requested, but the card is 0x AGP aka PCI) are communicated back via the same structure. 2) Is compatibility maintained by doing a match in AddMap and then returning the matching map? I handled the compat issue a little differently in MGA. Since I added a new ioctl, I could put the driver in either new mode or old mode. In old mode, everything worked *exactly* as before. In new mode, the map types / offsets were obtained differently. In fact, some of the maps are not available to user-mode in new mode (e.g., the MMIO register map). I think the answer to this question will vary from driver to driver. 3) Can the driver pre-build the AGP/PCI gart maps? If these maps are marked differently it is way for my driver to tell AGP from PCI cards. I would advise against that. There are (rare) cases where user-mode wants to select AGP parameters, AGP mode vs. PCI mode, etc. If AGP is acquired and those maps added at module load, the only way to make those selections will be via module paramters. Yuck. 4) Are there issues with sarea other than the one we talked about with XvMC? 5) I had set things up so that a reset program could access the register/framebuffer maps before the card was initialized. You need that because you can't initialize a card that hasn't been reset. BenH is working on another reset scheme so this may not be needed any more. One route that I had considered going for MGA was to have some of the maps created when the module loadad and some maps created in the DMA boot-strap ioctl. I didn't see a need to do that, so I decided to keep all the mapping code grouped together. I think it should be fine to go that way, though. 6) Is there some need for user space collecting info about the hardware and then feeding it back into the driver that I can't see? Yes and no. Detecting certain hardware features in the kernel can add extra bloat. For example, MGA needs to know (at least for G200) whether the card has SDRAM or SGRAM. It's easier to have that in user-mode so that you don't add a big chunk of one-time code to the kernel. This example is a little weak. I think there may be a different way to do this detection than the way X does it. Dunno. 7) Any more issues? -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.1 (MingW32) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFCwWjIX1gOwKyEAw8RAh2DAJ9gw8i3lDQ/+WX8WEPskWJu8VFi/QCfXAYN dwj7o6qd7BDT3dBLksD9vp8= =xwte -END PGP SIGNATURE- --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477alloc_id=16492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
On 6/28/05, Ian Romanick [EMAIL PROTECTED] wrote: 1) Should the maps be created once at driver load time or on open/close? I can probably make the egl drivers work either way. I did it at neither time in the MGA driver. When I added support there for PCI cards, I added a DMA boot-strap ioctl. User-mode passes in some parameters to the kernel (e.g., size of DMA buffers, requested AGP mode, etc.). The kernel then uses those parameters as guidelines to initialize itself. Any changes the kernel has to make (e.g., 4x AGP was requested, but the card is 0x AGP aka PCI) are communicated back via the same structure. A future development path might allow two independent users, one on each head. How do we handle them setting conflicting requests for AGP mode and DMA buffer size? Should AGP mode be a DRM property? It is easy to add an attribute to the driver. Same for DMA buffer size. We would try to pick the right default value for these in the driver. The attributes would only be used for override if the default was wrong. Make these attributes into DRM properties gets rid of the multiuser problem. 3) Can the driver pre-build the AGP/PCI gart maps? If these maps are marked differently it is way for my driver to tell AGP from PCI cards. I would advise against that. There are (rare) cases where user-mode wants to select AGP parameters, AGP mode vs. PCI mode, etc. If AGP is acquired and those maps added at module load, the only way to make those selections will be via module paramters. Yuck. Is it ok to let non-root users build these maps? Another solution would be to build a default set in and require root priv to override it. Module parameters aren't as bad as they used to be. You can echo/cat from /sys/module/driver/parameter and read/write them while the module is running. Just load the module and then change the defaults with a shell script. For example turn on drm debug while drm is running: echo 1 /sys/module/drm/debug 6) Is there some need for user space collecting info about the hardware and then feeding it back into the driver that I can't see? Yes and no. Detecting certain hardware features in the kernel can add extra bloat. For example, MGA needs to know (at least for G200) whether the card has SDRAM or SGRAM. It's easier to have that in user-mode so that you don't add a big chunk of one-time code to the kernel. This example is a little weak. I think there may be a different way to do this detection than the way X does it. Dunno. Since my drivers aren't running as root they have a hard time collecting info like this. Other solutions: 1) call_userhelper() - user mode driver helper that runs in root context 2) put the complex code in the driver and just mark it _init. It will go poof as soon as the driver load is finished. -- Jon Smirl [EMAIL PROTECTED] --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_idt77alloc_id492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
Hi! Some comments for current implementations of VIA chipsets: Jon Smirl wrote: We should discuss the design of DRM maps so that we don't work at cross purposes. The register map should be marked read only or root only. I don't need access to the register map. A lot of syncing is done using direct register reads, both with OpenGL and XvMC. I'll be needing read-only. 4) Are there issues with sarea other than the one we talked about with XvMC? Having thought a bit more about the SAREA problem, I'd like to see the following solution: 1) AddMap returns an error if the flag CONTAINS_LOCK is not set. The first SAREA otherwise for backwards compatibility. 2) The device-specific code returns the number of possible SAREAS and the size of each of them. 3) The first one (containing the lock) is created on init or on open for backwards compatibility. 4) subsequent ones are requested and created by a new IOCTL taking the sarea number as an argument. This IOCTL should be used also for future user space access to the first sarea, since standard lookup will fail if there are a number of SAREA maps greater than one. Refcount for destruction of subsequent maps? /Thomas --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477alloc_id=16492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
On 6/28/05, Thomas Hellström [EMAIL PROTECTED] wrote: Having thought a bit more about the SAREA problem, I'd like to see the following solution: 1) AddMap returns an error if the flag CONTAINS_LOCK is not set. The first SAREA otherwise for backwards compatibility. 2) The device-specific code returns the number of possible SAREAS and the size of each of them. 3) The first one (containing the lock) is created on init or on open for backwards compatibility. 4) subsequent ones are requested and created by a new IOCTL taking the sarea number as an argument. This IOCTL should be used also for future user space access to the first sarea, since standard lookup will fail if there are a number of SAREA maps greater than one. Refcount for destruction of subsequent maps? You can't let a normal user request an arbitrary number or size of sarea. If the API allows general requests it has to be root only. -- Jon Smirl [EMAIL PROTECTED] --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_idt77alloc_id492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
Jon Smirl wrote: On 6/28/05, Thomas Hellström [EMAIL PROTECTED] wrote: Having thought a bit more about the SAREA problem, I'd like to see the following solution: 1) AddMap returns an error if the flag CONTAINS_LOCK is not set. The first SAREA otherwise for backwards compatibility. 2) The device-specific code returns the number of possible SAREAS and the size of each of them. 3) The first one (containing the lock) is created on init or on open for backwards compatibility. 4) subsequent ones are requested and created by a new IOCTL taking the sarea number as an argument. This IOCTL should be used also for future user space access to the first sarea, since standard lookup will fail if there are a number of SAREA maps greater than one. Refcount for destruction of subsequent maps? You can't let a normal user request an arbitrary number or size of sarea. If the API allows general requests it has to be root only. You got me wrong. Item 2 above states that the device specific code specifies the number of possible SAREAS and their sizes to main DRM as part of its initialization. typically for two sareas something like static uint32_t via_sarea_sizes[] = {8192, 4096, 0}; static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, .context_ctor = via_init_context, .context_dtor = via_final_context, .vblank_wait = via_driver_vblank_wait, . .sarea_sizes = via_sarea_sizes; New user code can then get a handle to the first sarea by calling (implementation of a new ioctl) drmGetSAREA(0, handle, size); drmGetSAREA(1, handle, size); whereas drmGetSAREA(2,) and upwards would fail in this case. /Thomas --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_idt77alloc_id492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
On 6/28/05, Thomas Hellström [EMAIL PROTECTED] wrote: You got me wrong. Item 2 above states that the device specific code specifies the number of possible SAREAS and their sizes to main DRM as part of its initialization. typically for two sareas something like static uint32_t via_sarea_sizes[] = {8192, 4096, 0}; static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, .context_ctor = via_init_context, .context_dtor = via_final_context, .vblank_wait = via_driver_vblank_wait, . .sarea_sizes = via_sarea_sizes; New user code can then get a handle to the first sarea by calling (implementation of a new ioctl) drmGetSAREA(0, handle, size); drmGetSAREA(1, handle, size); whereas drmGetSAREA(2,) and upwards would fail in this case. /Thomas That will work since the amount of memory being allocated is constrained by the driver. -- Jon Smirl [EMAIL PROTECTED] --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_idt77alloc_id492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRM map design
On 6/28/05, Ian Romanick [EMAIL PROTECTED] wrote: 3) Can the driver pre-build the AGP/PCI gart maps? If these maps are marked differently it is way for my driver to tell AGP from PCI cards. I would advise against that. There are (rare) cases where user-mode wants to select AGP parameters, AGP mode vs. PCI mode, etc. If AGP is acquired and those maps added at module load, the only way to make those selections will be via module paramters. Yuck. Currently the drivers are AddMap'ing multiple little maps over the AGP area, but the area is basically split into two area: private for the master and public for the DRI clients to write to. So to get around the root priv requirement of AddMap I could have DRM initially create a map which only allows master access to AGP space. Then the non-root master could safely AddMap sub-maps which must exist inside of the predefined AGP map. These sub-maps would lower the priv requirements for parts of AGP space and allow the clients to run. -- Jon Smirl [EMAIL PROTECTED] --- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_idt77alloc_id492op=click -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel